kopia lustrzana https://github.com/SP8EBC/ParaTNC
nvm: measurement storage
rodzic
88fd2987cb
commit
acddab74e3
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.PERIPHERALS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <peripherals> <peripheral name="GPIOA"/> <peripheral name="RTC"/> <peripheral name="ADC2"/> </peripherals> "/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.PERIPHERALS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <peripherals> <peripheral name="FLASH"/> </peripherals> "/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
||||
|
@ -57,6 +57,6 @@
|
|||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"> <memoryBlockExpression address="134742016" label="0x8080000"/> <memoryBlockExpression address="134762496" label="0x8085000"/> <memoryBlockExpression address="134764544" label="0x8085800"/> </memoryBlockExpressionList> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
||||
|
|
|
@ -101,6 +101,8 @@ void main_service_cpu_load_ticks(void);
|
|||
|
||||
void main_reload_internal_wdg(void);
|
||||
|
||||
uint32_t main_get_nvm_timestamp(void);
|
||||
|
||||
#if defined(STM32L471xx)
|
||||
extern uint32_t rte_main_rx_total;
|
||||
extern uint32_t rte_main_tx_total;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define NVM_RECORD_SIZE 8 // in bytes!!
|
||||
|
||||
typedef struct __attribute__((packed)) nvm_measurement_t {
|
||||
/**
|
||||
* Date-time timestamp in timezone local for a place where station is installed.
|
||||
|
@ -22,16 +24,19 @@ typedef struct __attribute__((packed)) nvm_measurement_t {
|
|||
uint32_t timestamp;
|
||||
|
||||
/**
|
||||
* Temperature represented as 0.1 degrees increment and
|
||||
* Temperature represented as 0.2 degrees increment and
|
||||
* humidity in 2% steps
|
||||
* bit 0 - bit 9 === raw temperature, physical: raw / 10 - 50 (from -50.0 to +52.3)
|
||||
* bit 0 - bit 9 === raw temperature, physical: raw / 5 - 50 (from -50.0 to +52.3)
|
||||
* bit 10 - bit 15 === raw humidity, physical: raw * 2 (from 0% to 100%)
|
||||
*/
|
||||
uint16_t temperature_humidity;
|
||||
|
||||
/**
|
||||
* Average windspeed and gust windspeed stored in 0.2m/s increments
|
||||
* bit 0 - bit 7 === raw average windspeed, physical: raw / 5 (from 0m/s up to 50m/s)
|
||||
* bit 0 - bit 7 === raw average windspeed, physical: raw / 5 (from 0m/s up to 50m/s)
|
||||
* bit 9 - bit 12 === raw maximum windspeed, physical: physical_average + raw / 3
|
||||
* bit 13 - bit 16 === wind direction. lookup table:
|
||||
* 0 -
|
||||
*/
|
||||
uint16_t wind;
|
||||
|
||||
|
@ -47,5 +52,8 @@ typedef enum nvm_state_result_t {
|
|||
|
||||
void nvm_measurement_init(void);
|
||||
nvm_state_result_t nvm_measurement_store(nvm_measurement_t * data);
|
||||
void nvm_erase_all(void);
|
||||
|
||||
void nvm_test_prefill(void); ///<! Only for test purposes!
|
||||
|
||||
#endif /* NVM_H_ */
|
|
@ -25,6 +25,7 @@ void wx_get_all_measurements(const config_data_wx_sources_t * const config_sourc
|
|||
int32_t wx_get_bme280_temperature_pressure_humidity(float * const temperature, float * const pressure, int8_t * const humidity);
|
||||
void wx_pool_anemometer(const config_data_wx_sources_t * const config_sources, const config_data_mode_t * const config_mode, const config_data_umb_t * const config_umb, const config_data_rtu_t * const config_rtu);
|
||||
void wx_check_force_i2c_reset(void);
|
||||
|
||||
uint16_t wx_get_nvm_record_temperature(void);
|
||||
uint16_t wx_get_nvm_record_wind(void);
|
||||
|
||||
#endif /* WX_HANDLER_H_ */
|
||||
|
|
73
src/main.c
73
src/main.c
|
@ -165,6 +165,9 @@ const config_data_gsm_t * main_config_data_gsm = 0;
|
|||
// global variable incremented by the SysTick handler to measure time in miliseconds
|
||||
uint32_t master_time = 0;
|
||||
|
||||
// current timestamp from RTC in NVM format
|
||||
uint32_t main_nvm_timestamp = 0;
|
||||
|
||||
// this global variable stores numbers of ticks of idling CPU
|
||||
uint32_t main_idle_cpu_ticks = 0;
|
||||
|
||||
|
@ -396,6 +399,12 @@ int main(int argc, char* argv[]){
|
|||
main_crc_result = 0;
|
||||
|
||||
configuration_set_register(0);
|
||||
|
||||
#if defined(STM32L471xx)
|
||||
nvm_erase_all();
|
||||
|
||||
nvm_test_prefill();
|
||||
#endif
|
||||
}
|
||||
|
||||
// if first section has wrong CRC and it hasn't been restored before
|
||||
|
@ -1043,6 +1052,8 @@ int main(int argc, char* argv[]){
|
|||
#endif
|
||||
}
|
||||
|
||||
main_nvm_timestamp = main_get_nvm_timestamp();
|
||||
|
||||
// Infinite loop
|
||||
while (1)
|
||||
{
|
||||
|
@ -1351,6 +1362,8 @@ int main(int argc, char* argv[]){
|
|||
|
||||
main_set_monitor(4);
|
||||
|
||||
main_nvm_timestamp = main_get_nvm_timestamp();
|
||||
|
||||
#ifndef _MUTE_OWN
|
||||
packet_tx_handler(main_config_data_basic, main_config_data_mode);
|
||||
#endif
|
||||
|
@ -1561,6 +1574,66 @@ void main_reload_internal_wdg(void){
|
|||
#endif
|
||||
}
|
||||
|
||||
uint32_t main_get_nvm_timestamp(void) {
|
||||
uint32_t out = 0;
|
||||
|
||||
/**
|
||||
* Date-time timestamp in timezone local for a place where station is installed.
|
||||
* Mixture of BCD and integer format, this is just sligtly processed RTC registers
|
||||
* content.
|
||||
* bit 0 - bit 12 === number of minutes starting from midnight (max 1440)
|
||||
* bit 16 - bit 24 === days from new year (max 356)
|
||||
* bit 25 - bit 31 === years (from 00 to 99, from 2000 up to 2099)
|
||||
*/
|
||||
|
||||
#ifdef STM32L471xx
|
||||
|
||||
uint16_t temp = 0;
|
||||
|
||||
// minutes
|
||||
temp = 600 * ((RTC->TR & RTC_TR_HT) >> RTC_TR_HT_Pos) +
|
||||
60 * ((RTC->TR & RTC_TR_HU) >> RTC_TR_HU_Pos) +
|
||||
10 * ((RTC->TR & RTC_TR_MNT) >> RTC_TR_MNT_Pos) +
|
||||
1 * ((RTC->TR & RTC_TR_MNU) >> RTC_TR_MNU_Pos);
|
||||
|
||||
out = out | (temp & 0x7FF);
|
||||
|
||||
// current month
|
||||
temp = 1 * ((RTC->DR & RTC_DR_MU) >> RTC_DR_MU_Pos) +
|
||||
10 * ((RTC->DR & RTC_DR_MT) >> RTC_DR_MT_Pos);
|
||||
|
||||
switch (temp) {
|
||||
case 1: temp = 0; break;
|
||||
case 2: temp = 31; break;
|
||||
case 3: temp = 31 + 28; break;
|
||||
case 4: temp = 31 + 28 + 31; break;
|
||||
case 5: temp = 31 + 28 + 31 + 30; break;
|
||||
case 6: temp = 31 + 28 + 31 + 30 + 31; break;
|
||||
case 7: temp = 31 + 28 + 31 + 30 + 31 + 30; break;
|
||||
case 8: temp = 31 + 28 + 31 + 30 + 31 + 30 + 31; break;
|
||||
case 9: temp = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31; break;
|
||||
case 10:temp = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30; break;
|
||||
case 11:temp = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31; break;
|
||||
case 12:temp = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30; break;
|
||||
}
|
||||
|
||||
// then add number of days from current month
|
||||
temp = temp +
|
||||
1 * ((RTC->DR & RTC_DR_DU) >> RTC_DR_DU_Pos) +
|
||||
10 * ((RTC->DR & RTC_DR_DT) >> RTC_DR_DT_Pos);
|
||||
|
||||
out = out | ((temp & 0x1FF) << 16);
|
||||
|
||||
// years
|
||||
temp = 10 * ((RTC->DR & RTC_DR_YT) >> RTC_DR_YT_Pos) +
|
||||
1 * ((RTC->DR & RTC_DR_YU) >> RTC_DR_YU_Pos);
|
||||
|
||||
out = out | ((temp & 0x7F) << 25);
|
||||
|
||||
#endif
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
|
186
src/nvm.c
186
src/nvm.c
|
@ -20,7 +20,10 @@
|
|||
#endif
|
||||
|
||||
#define NVM_MEASUREMENT_OFFSET 0
|
||||
#define NVM_MEASUREMENT_MAXIMUM_SIZ (NVM_PAGE_SIZE * 96)
|
||||
#define NVM_MEASUREMENT_PAGES_USED 96
|
||||
#define NVM_MEASUREMENT_MAXIMUM_SIZ (NVM_PAGE_SIZE * NVM_MEASUREMENT_PAGES_USED)
|
||||
|
||||
#define START_OF_LAST_NVM_PAGE (nvm_base_address + NVM_MEASUREMENT_MAXIMUM_SIZ - NVM_PAGE_SIZE)
|
||||
|
||||
uint32_t nvm_base_address = 0;
|
||||
|
||||
|
@ -63,11 +66,11 @@ void nvm_measurement_init(void) {
|
|||
// check current flash size
|
||||
if (FLASH_SIZE == 1024 KB) {
|
||||
// 1024KB
|
||||
nvm_base_address = 0x08040000;
|
||||
nvm_base_address = 0x08080000;
|
||||
}
|
||||
else if (FLASH_SIZE == 512 KB) {
|
||||
// 512KB
|
||||
nvm_base_address = 0x08080000;
|
||||
nvm_base_address = 0x08040000;
|
||||
}
|
||||
else {
|
||||
// unknown device ??
|
||||
|
@ -136,6 +139,9 @@ void nvm_measurement_init(void) {
|
|||
nvm_general_state = NVM_OK;
|
||||
}
|
||||
|
||||
// disable programming
|
||||
FLASH->CR &= (0xFFFFFFFF ^ FLASH_CR_PG);
|
||||
|
||||
FLASH_Lock();
|
||||
}
|
||||
else {
|
||||
|
@ -147,16 +153,190 @@ void nvm_measurement_init(void) {
|
|||
|
||||
nvm_state_result_t nvm_measurement_store(nvm_measurement_t * data) {
|
||||
|
||||
nvm_state_result_t out = NVM_OK;
|
||||
|
||||
#if defined(STM32L471xx)
|
||||
|
||||
volatile uint32_t * src = (uint32_t *)data;
|
||||
|
||||
uint32_t next_page_addr = 0;
|
||||
|
||||
// flash operation result
|
||||
FLASH_Status flash_status = 0;
|
||||
|
||||
// check if there is a room for storage
|
||||
if (nvm_general_state == NVM_NO_SPACE_LEFT) {
|
||||
// erase first page of NVM flash area
|
||||
|
||||
nvm_data_ptr = (uint8_t*)nvm_base_address;
|
||||
|
||||
flash_status = FLASH_ErasePage(nvm_data_ptr);
|
||||
|
||||
if (flash_status == FLASH_COMPLETE) {
|
||||
nvm_general_state = NVM_OK;
|
||||
}
|
||||
else {
|
||||
nvm_general_state = NVM_PGM_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// check if currently last page is used
|
||||
if ((uint32_t)nvm_data_ptr < START_OF_LAST_NVM_PAGE) {
|
||||
// if not check if next page of flash memory is erased or not
|
||||
if (*(nvm_data_ptr + NVM_PAGE_SIZE) != 0xFF) {
|
||||
// an address somewhere within the next page of memory
|
||||
next_page_addr = (uint32_t)nvm_data_ptr + NVM_PAGE_SIZE;
|
||||
|
||||
// a start of next flash page
|
||||
next_page_addr = (next_page_addr / NVM_PAGE_SIZE) * NVM_PAGE_SIZE;
|
||||
|
||||
flash_status = FLASH_ErasePage(next_page_addr);
|
||||
|
||||
if (flash_status != FLASH_COMPLETE) {
|
||||
nvm_general_state = NVM_PGM_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FLASH_Unlock();
|
||||
|
||||
// check if NVM has been initialized and it is ready to work
|
||||
if (nvm_general_state != NVM_UNINITIALIZED) {
|
||||
// check if there is a room to store this measurement
|
||||
if (nvm_general_state != NVM_NO_SPACE_LEFT) {
|
||||
|
||||
// enable programming
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
|
||||
// progam this measurement
|
||||
for (int i = 0 ; i < NVM_RECORD_SIZE / 4; i++) {
|
||||
*((uint32_t*)(nvm_data_ptr) + i) = *(src + i);
|
||||
WAIT_FOR_PGM_COMPLETION
|
||||
|
||||
if (flash_status != FLASH_COMPLETE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// move data pointer
|
||||
nvm_data_ptr += NVM_WRITE_BYTE_ALIGN;
|
||||
|
||||
// and check if an end has
|
||||
if ((uint32_t)nvm_data_ptr < nvm_base_address + NVM_MEASUREMENT_MAXIMUM_SIZ) {
|
||||
;
|
||||
}
|
||||
else {
|
||||
out = NVM_NO_SPACE_LEFT;
|
||||
nvm_general_state = NVM_NO_SPACE_LEFT;
|
||||
}
|
||||
|
||||
// disable programming
|
||||
FLASH->CR &= (0xFFFFFFFF ^ FLASH_CR_PG);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
FLASH_Lock();
|
||||
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
void nvm_erase_all(void) {
|
||||
#if defined(STM32L471xx)
|
||||
|
||||
uint32_t base_address = 0;
|
||||
|
||||
FLASH_Unlock();
|
||||
|
||||
// check current flash size
|
||||
if (FLASH_SIZE == 1024 KB) {
|
||||
// 1024KB
|
||||
base_address = 0x08080000;
|
||||
}
|
||||
else if (FLASH_SIZE == 512 KB) {
|
||||
// 512KB
|
||||
base_address = 0x08040000;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NVM_MEASUREMENT_PAGES_USED; i++) {
|
||||
FLASH_ErasePage(base_address + (i * NVM_PAGE_SIZE));
|
||||
}
|
||||
|
||||
FLASH_Lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void nvm_test_prefill(void) {
|
||||
#if defined(STM32L471xx)
|
||||
|
||||
uint32_t * base_address = 0;
|
||||
|
||||
// flash operation result
|
||||
FLASH_Status flash_status = 0;
|
||||
|
||||
FLASH_Unlock();
|
||||
|
||||
// enable programming
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
|
||||
// check current flash size
|
||||
if (FLASH_SIZE == 1024 KB) {
|
||||
// 1024KB
|
||||
base_address = (uint32_t *)0x08080000;
|
||||
}
|
||||
else if (FLASH_SIZE == 512 KB) {
|
||||
// 512KB
|
||||
base_address = (uint32_t *)0x08040000;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
// program first 10 pages of flash with 0xABCDABCD / 0x99889988
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
// flash programming must be 64 bit (8 bytes) aligned
|
||||
for (int j = 0; j < NVM_PAGE_SIZE / 8; j++) {
|
||||
*(base_address++) = 0xABCDABCD;
|
||||
WAIT_FOR_PGM_COMPLETION
|
||||
|
||||
*(base_address++) = 0x99889988;
|
||||
WAIT_FOR_PGM_COMPLETION
|
||||
}
|
||||
}
|
||||
|
||||
if (FLASH_SIZE == 1024 KB) {
|
||||
// 1024KB
|
||||
base_address = (uint32_t *)(0x08080000 + 11 * NVM_PAGE_SIZE);
|
||||
}
|
||||
else if (FLASH_SIZE == 512 KB) {
|
||||
// 512KB
|
||||
base_address = (uint32_t *)(0x08040000 + 11 * NVM_PAGE_SIZE);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 11; i < NVM_MEASUREMENT_PAGES_USED; i++) {
|
||||
// flash programming must be 64 bit (8 bytes) aligned
|
||||
for (int j = 0; j < NVM_PAGE_SIZE / 8; j++) {
|
||||
*(base_address++) = 0x12345678;
|
||||
WAIT_FOR_PGM_COMPLETION
|
||||
|
||||
*(base_address++) = 0x99999999;
|
||||
WAIT_FOR_PGM_COMPLETION
|
||||
}
|
||||
}
|
||||
// disable programming
|
||||
FLASH->CR &= (0xFFFFFFFF ^ FLASH_CR_PG);
|
||||
|
||||
FLASH_Lock();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "aprsis.h"
|
||||
#include "api/api.h"
|
||||
#include "pwr_save.h"
|
||||
#include "nvm.h"
|
||||
#endif
|
||||
|
||||
#include "main.h"
|
||||
|
@ -60,6 +61,7 @@ uint8_t packet_tx_trigger_tcp = 0;
|
|||
#define APRSIS_TRIGGER_METEO (1 << 3)
|
||||
#define RECONNECT_APRSIS (1 << 7)
|
||||
|
||||
nvm_measurement_t packet_tx_nvm;
|
||||
#endif
|
||||
|
||||
void packet_tx_send_wx_frame(void) {
|
||||
|
@ -234,6 +236,15 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
|||
// check if there is a time to send meteo packet through RF
|
||||
if (packet_tx_meteo_counter >= packet_tx_meteo_interval && packet_tx_meteo_interval != 0) {
|
||||
|
||||
#ifdef STM32L471xx
|
||||
packet_tx_nvm.temperature_humidity = wx_get_nvm_record_temperature();
|
||||
packet_tx_nvm.wind = wx_get_nvm_record_wind();
|
||||
packet_tx_nvm.timestamp = main_get_nvm_timestamp();
|
||||
|
||||
// write to NVM if it is enabled
|
||||
nvm_measurement_store(&packet_tx_nvm);
|
||||
#endif
|
||||
|
||||
// this function is required if more than one RF frame will be send from this function at once
|
||||
// it waits for transmission completion and add some delay to let digipeaters do theris job
|
||||
packet_tx_multi_per_call_handler();
|
||||
|
|
|
@ -349,4 +349,72 @@ void wx_pool_anemometer(const config_data_wx_sources_t * const config_sources, c
|
|||
|
||||
}
|
||||
|
||||
uint16_t wx_get_nvm_record_temperature(void) {
|
||||
|
||||
uint16_t out = 0;
|
||||
uint16_t scaled_temperature = 0;
|
||||
uint16_t scaled_humidity = 0;
|
||||
|
||||
if (rte_wx_temperature_average_external_valid > -50.0f && rte_wx_temperature_average_external_valid < 50.0f) {
|
||||
scaled_temperature = (uint16_t)((rte_wx_temperature_average_external_valid + 50.0f) * 5.0f);
|
||||
}
|
||||
|
||||
scaled_humidity = rte_wx_humidity_valid / 2;
|
||||
|
||||
out = (scaled_temperature & 0x1FF) | ((scaled_humidity & 0x1F) << 10);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
uint16_t wx_get_nvm_record_wind(void) {
|
||||
|
||||
uint16_t out = 0;
|
||||
|
||||
uint8_t scaled_average_windspeed = 0;
|
||||
uint8_t scaled_windgusts = 0;
|
||||
uint8_t wind_direction = 0;
|
||||
|
||||
scaled_average_windspeed = rte_wx_average_windspeed / 2;
|
||||
if ((rte_wx_max_windspeed - scaled_average_windspeed) < 52) {
|
||||
scaled_windgusts = (uint8_t)lroundf((rte_wx_max_windspeed - scaled_average_windspeed) / 3.0f);
|
||||
}
|
||||
|
||||
if (wind_direction <= 11 && wind_direction >= 349)
|
||||
wind_direction = 0;
|
||||
else if (wind_direction <= 34 && wind_direction > 11)
|
||||
wind_direction = 1;
|
||||
else if (wind_direction <= 56 && wind_direction > 34)
|
||||
wind_direction = 2;
|
||||
else if (wind_direction <= 79 && wind_direction > 56)
|
||||
wind_direction = 3;
|
||||
else if (wind_direction <= 101 && wind_direction > 79)
|
||||
wind_direction = 4;
|
||||
else if (wind_direction <= 124 && wind_direction > 101)
|
||||
wind_direction = 5;
|
||||
else if (wind_direction <= 146 && wind_direction > 124)
|
||||
wind_direction = 6;
|
||||
else if (wind_direction <= 169 && wind_direction > 146)
|
||||
wind_direction = 7;
|
||||
else if (wind_direction <= 191 && wind_direction > 169)
|
||||
wind_direction = 8;
|
||||
else if (wind_direction <= 214 && wind_direction > 191)
|
||||
wind_direction = 9;
|
||||
else if (wind_direction <= 236 && wind_direction > 214)
|
||||
wind_direction = 10;
|
||||
else if (wind_direction <= 259 && wind_direction > 236)
|
||||
wind_direction = 11;
|
||||
else if (wind_direction <= 281 && wind_direction > 259)
|
||||
wind_direction = 12;
|
||||
else if (wind_direction <= 304 && wind_direction > 281)
|
||||
wind_direction = 13;
|
||||
else if (wind_direction <= 327 && wind_direction > 304)
|
||||
wind_direction = 14;
|
||||
else if (wind_direction <= 349 && wind_direction > 327)
|
||||
wind_direction = 15;
|
||||
else;
|
||||
|
||||
out = (scaled_average_windspeed | (scaled_windgusts & 0xF) << 8 | (wind_direction & 0xF) << 12 );
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "./drivers/l4/flash_stm32l4x.h"
|
||||
#include "stm32l4xx.h"
|
||||
|
||||
#define KB *1024
|
||||
|
||||
|
||||
#define FLASH_KEY1 0x45670123U /*!< Flash key1 */
|
||||
#define FLASH_KEY2 0xCDEF89ABU /*!< Flash key2: used with FLASH_KEY1
|
||||
to unlock the FLASH registers access */
|
||||
|
@ -74,14 +77,27 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
|
|||
|
||||
uint32_t Banks = 0;
|
||||
|
||||
// calculate the bank number
|
||||
if (Page_Address < 0x08080000) {
|
||||
Banks = FLASH_BANK_1;
|
||||
if (FLASH_SIZE == 1024 KB) {
|
||||
// calculate the bank number
|
||||
if (Page_Address < 0x08080000) {
|
||||
Banks = FLASH_BANK_1;
|
||||
}
|
||||
else {
|
||||
Banks = FLASH_BANK_2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Banks = FLASH_BANK_2;
|
||||
else if (FLASH_SIZE == 512 KB) {
|
||||
// calculate the bank number
|
||||
if (Page_Address < 0x08040000) {
|
||||
Banks = FLASH_BANK_1;
|
||||
}
|
||||
else {
|
||||
Banks = FLASH_BANK_2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
FLASH_Unlock();
|
||||
|
||||
Page = Page_Address - 0x08000000 - (0x80000 * (Banks - 1));
|
||||
|
|
Ładowanie…
Reference in New Issue