diff --git a/stm32l4a6zg-f0x.at1/.cproject b/stm32l4a6zg-f0x.at1/.cproject
index 780452c..b107ccd 100644
--- a/stm32l4a6zg-f0x.at1/.cproject
+++ b/stm32l4a6zg-f0x.at1/.cproject
@@ -24,7 +24,7 @@
-
+
@@ -181,4 +181,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/stm32l4a6zg-f0x.at1/Core/Inc/commands.h b/stm32l4a6zg-f0x.at1/Core/Inc/commands.h
index 36bf227..bea15c8 100644
--- a/stm32l4a6zg-f0x.at1/Core/Inc/commands.h
+++ b/stm32l4a6zg-f0x.at1/Core/Inc/commands.h
@@ -22,6 +22,7 @@ extern RTC_HandleTypeDef hrtc;
/* function prototypes */
int do_help(char *args);
int do_devid(char *args);
+int do_frequ(char *args);
int do_info(char *args);
int do_sinfo(char *args);
int do_test(/*command_inst_t inst,*/ char *args);
diff --git a/stm32l4a6zg-f0x.at1/Core/Inc/helper.h b/stm32l4a6zg-f0x.at1/Core/Inc/helper.h
index bf0cb72..6d82b82 100644
--- a/stm32l4a6zg-f0x.at1/Core/Inc/helper.h
+++ b/stm32l4a6zg-f0x.at1/Core/Inc/helper.h
@@ -21,6 +21,8 @@ char *ltrim(char *s);
char *rtrim(char *s);
char *trim(char *s);
+int strtouint32 (char *s, uint32_t *uint32);
+
int strtotime (char *s, struct _tm_ *tp);
// uint8_t dayofweek(uint8_t century, uint8_t y, uint8_t m, uint8_t d);
diff --git a/stm32l4a6zg-f0x.at1/Core/Inc/si5351.h b/stm32l4a6zg-f0x.at1/Core/Inc/si5351.h
index 94035a3..403be8e 100644
--- a/stm32l4a6zg-f0x.at1/Core/Inc/si5351.h
+++ b/stm32l4a6zg-f0x.at1/Core/Inc/si5351.h
@@ -72,6 +72,16 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
/* #include could also be included */
/* Private includes ----------------------------------------------------------*/
+/* @brief SI5351 synthesis settings */
+typedef struct {
+ uint32_t pll_multiplier; /*!< corresponds to feedback multisynth (N) a */
+ uint32_t pll_numerator; /*!< corresponds to feedback multisynth (N) b */
+ uint32_t pll_denominator; /*!< corresponds to feedback multisynth (N) c */
+ uint32_t out_multiplier; /*!< corresponds to multisynth (M) a */
+ uint32_t out_numerator; /*!< corresponds to multisynth (M) b */
+ uint32_t out_denominator; /*!< corresponds to multisynth (M) c */
+ uint8_t out_r_divider; /*!< R divider, log2 value bit set to 1; 2,4,8,...,128; for frequencies < 500 kHz, otherwise set to 1 i.e. bit 0 */
+} synthesis_t;
/* Exported types ------------------------------------------------------------*/
/*!< Si5351 instance typedef -- handle as pointer */
@@ -129,6 +139,7 @@ int si5351_enable_output(si5351_inst_t inst, uint8_t clk);
int si5351_disable_output(si5351_inst_t inst, uint8_t clk);
int si5351_set_clk0(si5351_inst_t inst, uint32_t frequency);
int si5351_set_clk(si5351_inst_t inst, uint8_t clk, uint32_t frequency, si5351_pll_t pll);
+int si5351_set_frequency(si5351_inst_t inst, uint32_t frequency);
char * si5351_read_debug_msg(si5351_inst_t inst);
char * si5351_read_register_debug(si5351_inst_t inst, char *buf, size_t bufsize, uint8_t regaddr);
@@ -137,6 +148,11 @@ char * si5351_read_register_debug(si5351_inst_t inst, char *buf, size_t bufsize,
int si5351_get_instance(si5351_inst_t *inst);
int si5351_get_i2c_address(si5351_inst_t inst);
void* si5351_get_i2c_handle(si5351_inst_t inst);
+uint32_t si5351_get_frequency(si5351_inst_t inst);
+uint32_t si5351_get_xtal(si5351_inst_t inst);
+
+
+synthesis_t si5351_calculation(uint32_t frequency, uint32_t xtal);
/* under development */
int si5351_set_clk_phase(si5351_inst_t inst, uint8_t clk, uint32_t frequency, double phase, si5351_pll_t pll);
diff --git a/stm32l4a6zg-f0x.at1/Core/Src/commands.c b/stm32l4a6zg-f0x.at1/Core/Src/commands.c
index 0ec5c6f..08b8ce3 100644
--- a/stm32l4a6zg-f0x.at1/Core/Src/commands.c
+++ b/stm32l4a6zg-f0x.at1/Core/Src/commands.c
@@ -53,6 +53,7 @@ static const cmd_table_t cmd_table[] = {
{"altitude", 1, CMD_NO_FLAG, do_test },
{"date", 1, CMD_NO_FLAG, do_time },
{"devid", 3, CMD_HIDDEN, do_devid },
+ {"frequency",1, CMD_NO_FLAG, do_frequ },
{"help", 1, CMD_NO_FLAG, do_help },
{"hidden", 2, CMD_HIDDEN, do_test },
{"info", 1, CMD_NO_FLAG, do_info },
@@ -135,19 +136,57 @@ int do_devid(char *args) {
uint32_t myint[2];
char mychar[8];
} my;
- //char lot[sizeof(my) + 1];
printf("DEVID: 0x%08lx\n", HAL_GetDEVID());
printf("REVID: 0x%08lx\n", HAL_GetREVID());
- printf("UID: 0x%08lx %08lx %08lx\n", HAL_GetUIDw2(), HAL_GetUIDw1(), HAL_GetUIDw0());
+ printf("UID: 0x %08lx %08lx %08lx\n", HAL_GetUIDw2(), HAL_GetUIDw1(), HAL_GetUIDw0());
- my.myint[1] = HAL_GetUIDw2();
my.myint[0] = HAL_GetUIDw1();
- //memcpy(lot, my.mychar, sizeof(my.mychar));
- //lot[sizeof(my)] = '\0';
+ my.myint[1] = HAL_GetUIDw2();
- printf("=> Lot Number: %.8s\n", my.mychar);
+ printf("=> X: %2lx, Y: %2lx\n", HAL_GetUIDw0() >> 16, HAL_GetUIDw0() & 0xffff);
+ printf("=> Lot Number: %.6s\n", my.mychar + 1);
printf("=> Wafer Number: %u\n", (uint8_t)(HAL_GetUIDw1() & 0xff));
+ // printf("=> 1.Char: %x, 8.Char: %x\n", my.mychar[0], my.mychar[7]);
+
+ return 0;
+}
+
+int do_frequ(char *args) {
+ int rv;
+ (void)args;
+ si5351_inst_t inst = NULL;
+ uint32_t frequency;
+ uint32_t xtal_frequency;
+
+ rv = si5351_get_instance(&inst);
+ if (rv > 0) {
+ if (rv == 1) {
+ /* nothing */
+ }
+ if (!args) {
+ printf("Frequency: %lu Hz\n", si5351_get_frequency(inst));
+ } else {
+ rv = strtouint32(args, &frequency);
+ if (!rv) {
+ synthesis_t syn;
+ xtal_frequency = si5351_get_xtal(inst);
+ syn = si5351_calculation(frequency, xtal_frequency);
+
+ printf("out_r_divider: %u\n", syn.out_r_divider);
+ printf("out_multiplier: %lu\n", syn.out_multiplier);
+ printf("out_numerator: %lu\n", syn.out_numerator);
+ printf("out_denumerator:%lu\n",syn.out_denominator);
+
+ printf("pll_multiplier: %lu\n", syn.pll_multiplier);
+ printf("pll_numerator: %lu\n", syn.pll_numerator);
+ printf("pll_denominator:%lu\n", syn.pll_denominator);
+
+ rv = si5351_set_frequency(inst, frequency);
+
+ }
+ }
+ }
return 0;
}
@@ -165,7 +204,7 @@ int do_sinfo(char *args) {
printf("%d Si5351 instance%s found.\n", rv, (rv==1)?"":"s");
while (rv > 0) {
printf("Si5351 Handle: 0x%08lx\n", (uint32_t)inst);
-
+ printf(" I2C address: 0x%02x\n", si5351_get_i2c_address(inst));
rv = si5351_get_instance(&inst);
}
return rv;
diff --git a/stm32l4a6zg-f0x.at1/Core/Src/helper.c b/stm32l4a6zg-f0x.at1/Core/Src/helper.c
index ef5de58..b232cfc 100644
--- a/stm32l4a6zg-f0x.at1/Core/Src/helper.c
+++ b/stm32l4a6zg-f0x.at1/Core/Src/helper.c
@@ -21,7 +21,7 @@
#endif
/* do not use the #include library */
#include "helper.h"
-
+#include
char *ltrim(char *s)
{
while(isspace((int)*s)) s++;
@@ -41,6 +41,14 @@ char *trim(char *s)
return rtrim(ltrim(s));
}
+/* string to uint32_t */
+int strtouint32 (char *s, uint32_t * uint32) {
+ int rv = 0;
+ *uint32 = strtoul(s, &s, 10);
+ if (errno != 0)
+ return errno;
+ return rv;
+}
/* this is ISO 8601 2018-12-31 with separator == '-' */
int strtotime (char *s, struct _tm_ *tp) {
diff --git a/stm32l4a6zg-f0x.at1/Core/Src/main.c b/stm32l4a6zg-f0x.at1/Core/Src/main.c
index 349c847..908fc3e 100644
--- a/stm32l4a6zg-f0x.at1/Core/Src/main.c
+++ b/stm32l4a6zg-f0x.at1/Core/Src/main.c
@@ -28,7 +28,10 @@
#include "commands.h"
#include
#include "ringbuf.h"
+#if 0
#include "ringbuf_test.h" // test the ringbuffer
+#endif
+
#include "helper.h" // my toolbox for strings, etc.
/* USER CODE END Includes */
@@ -191,7 +194,6 @@ int main(void)
print_system_info();
// do some tests for ringbuf.h library
-
ring = ringbuf_create(mainbuf_size, RINGBUF_ALLOWOVERWRITE);
if (ring == NULL)
puts("Can't create memory for ringbuffer");
@@ -200,9 +202,9 @@ int main(void)
(void)ringbuf_callback_register(ring, ringbuffer_callback, NULL);
// #define NDEBUG
- // ringbuf_test();
+ //ringbuf_test();
- // 1st SI5351 chip at the I2C bus "hi2c1", address line A0 = 0
+ // 1st SI5351 chip at the I2C bus "hi2c1", address line A0 = 0 i.e. address = 0x60
si5351_inst = si5351_init(&hi2c1, 0x60, 25000000);
{
int ready = si5351_i2c_ready(si5351_inst);
@@ -220,9 +222,6 @@ int main(void)
printf("Device #1 gets status %d\n", status);
printf("Debug:\n%s", si5351_read_debug_msg(instance_si5351[1]));
#endif
- // si5351_set_clk0(instance_si5351[1], 3579545);
- // si5351_set_clk0(instance_si5351[1], 3580000);
- // si5351_set_clk0(instance_si5351[1], 4000000);
#if 0
si5351_set_clk0(instance_si5351[1], 3510000);
si5351_enable_output(instance_si5351[1],0);
@@ -340,7 +339,6 @@ int main(void)
/* Create the semaphores(s) */
/* creation of si5351 */
si5351Handle = osSemaphoreNew(1, 0, &si5351_attributes);
-
/* creation of command */
commandHandle = osSemaphoreNew(1, 0, &command_attributes);
diff --git a/stm32l4a6zg-f0x.at1/Core/Src/si5351.c b/stm32l4a6zg-f0x.at1/Core/Src/si5351.c
index 84f54dd..b50369b 100644
--- a/stm32l4a6zg-f0x.at1/Core/Src/si5351.c
+++ b/stm32l4a6zg-f0x.at1/Core/Src/si5351.c
@@ -45,28 +45,20 @@ typedef struct __SI5351_HandleTypeDef {
void *i2c_handle; /*!< the I2C handle, must not be unique */
struct __SI5351_HandleTypeDef *next; /*!< used for several instances */
uint32_t xtal_frequency; /*!< XTAL or CLKIN frequency */
+ uint32_t frequency; /*!< Si5351 output frequency */
#if SI5351_DEBUG
char debug_msg[1000]; /*!< for debugging msgs, extensive tests, N/A */
#endif
uint8_t clk_is_pllb; /*!< assignment of PLLA or PLLB per CLK #, if bit set to 1 ...PLLB */
uint8_t clk_is_disabled; /*!< assignment of Output Enable Control, app. Register 3 */
uint8_t clk_has_phase_shift;/*!< assignment of an output with a phase shift offset */
- uint8_t i2c_address; /*!< I2C address of the datasheet */
+ uint8_t i2c_address; /*!< I2C address of the datasheet shifted to left to match the characteristics of the HAL driver */
uint8_t interrupt_status_mask; /*!< Reg 2: Interrupt Status Mask */
uint8_t initialized :1; /*!< mark the driver initialized */
uint8_t programmed :1; /*!< mark the chip is programmed */
} si5351_HandleTypeDef;
-/* @brief SI5351 synthesis settings */
-typedef struct {
- uint32_t pll_multiplier; /*!< corresponds to feedback multisynth (N) a */
- uint32_t pll_numerator; /*!< corresponds to feedback multisynth (N) b */
- uint32_t pll_denominator; /*!< corresponds to feedback multisynth (N) c */
- uint32_t out_multiplier; /*!< corresponds to multisynth (M) a */
- uint32_t out_numerator; /*!< corresponds to multisynth (M) b */
- uint32_t out_denominator; /*!< corresponds to multisynth (M) c */
- uint8_t out_r_divider; /*!< R divider, log2 value bit set to 1; 2,4,8,...,128; for frequencies < 500 kHz, otherwise set to 1 i.e. bit 0 */
-} synthesis_t;
+
typedef struct {
char band[4];
@@ -458,6 +450,9 @@ static int band_select(uint32_t frequency, band_t *band) {
{"180", 1500000, 2250000, 400, 0 },
{"120", 2250000, 3000000, 300, 0 },
{ "60", 4500000, 5625000, 160, 0 },
+ /* don't know if this works: */
+ {"300", 500000, 1500000, 500, 0 },
+ {"500", 99999, 500000, 2000,0 },
};
/* possibly this could be improved with a bsearch algorithm: */
for (uint32_t i = 0; i < (sizeof(sband) / sizeof(sband[0])); i++) {
@@ -608,6 +603,8 @@ int si5351_set_clk0(si5351_inst_t inst, uint32_t frequency) {
(void) calculation(frequency, inst->xtal_frequency, &synth);
rv = si5351_set_synthesis(inst, &synth, 0);
} while (0);
+ if (rv == 0)
+ inst->frequency = frequency;
return rv;
}
@@ -782,15 +779,14 @@ static int si5351_set_synthesis(si5351_inst_t inst, synthesis_t *synth, uint8_t
assert(clk < 8);
assert(synth->out_r_divider < 8); /* the divider is stored in 3 bits and the value is 2^out_r_divider */
- assert(
- synth->pll_multiplier >= 4u && synth->pll_multiplier <= 2048u
+ assert(synth->pll_multiplier >= 4u && synth->pll_multiplier <= 2048u
&& synth->pll_multiplier != 5u
&& synth->pll_multiplier != 7u);
assert(synth->pll_denominator != 0u && synth->pll_denominator < (1u << 20)); // MSNx_P3 maximum of 1048575
- assert(
- synth->out_multiplier >= 4u && synth->out_multiplier <= 2048u
- && synth->out_multiplier != 5u
- && synth->out_multiplier != 7u);
+ assert(synth->out_multiplier >= 4u);
+ assert(synth->out_multiplier <= 2048u);
+ assert(synth->out_multiplier != 5u);
+ assert(synth->out_multiplier != 7u);
assert(synth->out_denominator != 0u && synth->out_denominator < (1u << 20));
/* PLL registers */
@@ -990,7 +986,7 @@ int si5351_get_i2c_address(si5351_inst_t inst) {
if (!inst && !(inst = first_handle))
return -EINVAL;
- return inst->i2c_address;
+ return inst->i2c_address >> 1; /* shift the given address from HAL conformity (shift one bit right) */
}
void* si5351_get_i2c_handle(si5351_inst_t inst) {
@@ -1000,3 +996,28 @@ void* si5351_get_i2c_handle(si5351_inst_t inst) {
return (void*) inst->i2c_handle;
}
+int si5351_set_frequency(si5351_inst_t inst, uint32_t frequency) {
+ /* some checks ?? */
+ return si5351_set_clk0(inst, frequency);
+}
+
+uint32_t si5351_get_frequency(si5351_inst_t inst) {
+ if (!inst && !(inst = first_handle))
+ return -EINVAL;
+
+ return inst->frequency;
+}
+
+uint32_t si5351_get_xtal(si5351_inst_t inst) {
+ if (!inst && !(inst = first_handle))
+ return -EINVAL;
+
+ return inst->xtal_frequency;
+}
+
+synthesis_t si5351_calculation(uint32_t frequency, uint32_t xtal) {
+
+ synthesis_t st;
+ (void) calculation(frequency, xtal, &st);
+ return st;
+}