- Fix bug in flash sector allocation for F413.
- Fix bug in rxafsk releasing object FIFO.
Development
bob 2018-10-15 00:35:18 +11:00
rodzic 61188565ab
commit a6e0c85e4d
15 zmienionych plików z 549 dodań i 542 usunięć

Wyświetl plik

@ -209,7 +209,7 @@ const SerialConfig debug_config = {
/*===========================================================================*/
void pktConfigSerialDiag(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_EXTERNAL_I2C == FALSE && ENABLE_SERIAL_DEBUG == TRUE
/* USART3 TX. */
palSetLineMode(LINE_USART3_TX, PAL_MODE_ALTERNATE(7));
/* USART3 RX. */
@ -234,7 +234,7 @@ uint8_t pktReadIOlines() {
void pktSerialStart(void) {
#if ENABLE_SERIAL_DEBUG == TRUE
pktConfigSerialDiag();
sdStart(SERIAL_CFG_DEBUG_DRIVER, &debug_config);
sdStart(&SERIAL_CFG_DEBUG_DRIVER, &debug_config);
#endif
/* Setup diagnostic resource access semaphore. */
//extern binary_semaphore_t debug_out_sem;
@ -244,7 +244,7 @@ void pktSerialStart(void) {
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_SERIAL_DEBUG == TRUE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
chnWrite((BaseSequentialStream*)&SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
@ -270,7 +270,7 @@ int dbgPrintf(uint8_t level, const char *format, ...) {
void pktWrite(uint8_t *buf, uint32_t len) {
#if ENABLE_SERIAL_DEBUG == TRUE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
chnWrite((BaseSequentialStream*)&SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;

Wyświetl plik

@ -161,7 +161,7 @@
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C TRUE
#define ENABLE_EXTERNAL_I2C FALSE
#define EI2C_SCL LINE_IO_TXD /* SCL */
#define EI2C_SDA LINE_IO_RXD /* SDA */

Wyświetl plik

@ -239,9 +239,6 @@
#define GPIOK_PIN14 14U
#define GPIOK_PIN15 15U
/*
* IO lines assignments.
*/
/* For enabling TCXO. Done in early_init. */
#define LINE_TCXO_EN PAL_LINE(GPIOC, 13U)

Wyświetl plik

@ -214,16 +214,6 @@ void pktConfigSerialDiag(void) {
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
}
/**
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
/*ioline_t pktSetLineModeICU(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
return LINE_ICU;
}*/
/*
* Read GPIO that are used for:
* a) general use

Wyświetl plik

@ -29,7 +29,7 @@ const conf_t conf_flash_default = {
.cca = 0x5F,
},
// App identity
.call = "VK2GJ-6",
.call = "VK2GJ-5",
.path = "WIDE1-1",
.symbol = SYM_DIGIPEATER,
.aprs_msg = false, // Enable APRS message reception on this app
@ -141,8 +141,8 @@ const conf_t conf_flash_default = {
// If duration is TIME_INFINITE then the radio stays active while the thread waits forever.
.active = true,
.init_delay = TIME_S2I(20),
.cycle = CYCLE_CONTINUOUSLY,
.interval = 0
.cycle = TIME_S2I(60),
.interval = TIME_S2I(45)
},
// Receive radio configuration
.radio_conf = {
@ -165,7 +165,7 @@ const conf_t conf_flash_default = {
.cca = 0x5F
},
// Digipeat transmission identity
.call = "VK2GJ-6",
.call = "VK2GJ-5",
.path = "WIDE2-1",
.symbol = SYM_DIGIPEATER,
// A digipeater beacon can be added using one of the POS apps

Wyświetl plik

@ -248,16 +248,16 @@ THD_FUNCTION(pktConsole, arg) {
event_listener_t shell_el;
/*Wait for start permission. */
thread_t *initiator = chMsgWait();
(void)chMsgGet(initiator);
//thread_t *initiator = chMsgWait();
//(void)chMsgGet(initiator);
console_state = CON_CHN_INIT;
/* Signal that basic init is done. */
chMsgRelease(initiator, MSG_OK);
//chMsgRelease(initiator, MSG_OK);
/* Wait for serial channel to be started for us. */
initiator = chMsgWait();
thread_t *initiator = chMsgWait();
(void)chMsgGet(initiator);
/* Attach event listener to serial channel. */
@ -273,6 +273,9 @@ THD_FUNCTION(pktConsole, arg) {
NULL
};
(void)chEvtGetAndClearEvents(CONSOLE_CHANNEL_EVT);
(void)chEvtGetAndClearFlags(&con_el);
/* Flag that channel setup is done. */
chMsgRelease(initiator, MSG_OK);
@ -334,7 +337,7 @@ THD_FUNCTION(pktConsole, arg) {
console_state = CON_CHN_SHELL;
/* Wait for next event. */
continue;
} /* End case CON_CHN_CONNECT or CON_CHN_WAIT. */
} /* End case CON_CHN_CONNECT, CON_CHN_WAIT or CON_CHN_FLUSH. */
default:
/* Check if there was a shell event. */
@ -404,7 +407,7 @@ msg_t pktStartConsole(BaseAsynchronousChannel *ser) {
msg_t smsg = chMsgSend(con_thd, MSG_OK);
/* Signal thread to enter trace output and shell request monitoring. */
smsg = chMsgSend(con_thd, MSG_OK);
//smsg = chMsgSend(con_thd, MSG_OK);
return smsg;
}

Wyświetl plik

@ -111,7 +111,7 @@ void debug_print(char *type, char* filename, uint32_t line, char* format, ...)
chvprintf((BaseSequentialStream*)&SERIAL_DEBUG_DRIVER, format, args);
va_end(args);
chprintf((BaseSequentialStream*)&SERIAL_DEBUG_DRIVER, "\r\n");
#endif
#endif /* ENABLE_SERIAL_DEBUG == TRUE */
chMtxUnlock(&debug_mtx);
}

Wyświetl plik

@ -1,278 +1,280 @@
/**
* Flash driver
* The driver code origin is
* https://github.com/mabl/ARMCM3-STM32F107-BOOTLOADER/tree/master/ARMCM3-STM32F107-BOOTLOADER/flash
* https://github.com/tegesoft/flash-stm32f407/tree/master/flash
*/
#include "flash.h"
#include <string.h>
size_t flashSectorSize(flashsector_t sector)
{
if (sector <= 3)
return 16 * 1024;
else if (sector == 4)
return 64 * 1024;
else if (sector >= 5 && sector <= 11)
return 128 * 1024;
return 0;
}
flashaddr_t flashSectorBegin(flashsector_t sector)
{
flashaddr_t address = FLASH_BASE;
while (sector > 0)
{
--sector;
address += flashSectorSize(sector);
}
return address;
}
flashaddr_t flashSectorEnd(flashsector_t sector)
{
return flashSectorBegin(sector + 1);
}
flashsector_t flashSectorAt(flashaddr_t address)
{
flashsector_t sector = 0;
while (address >= flashSectorEnd(sector))
++sector;
return sector;
}
/**
* @brief Wait for the flash operation to finish.
*/
#define flashWaitWhileBusy() { while (FLASH->SR & FLASH_SR_BSY) {} }
/**
* @brief Unlock the flash memory for write access.
* @return TRUE Unlock was successful.
* @return FALSE Unlock failed.
*/
static bool flashUnlock(void)
{
/* Check if unlock is really needed */
if (!(FLASH->CR & FLASH_CR_LOCK))
return TRUE;
/* Write magic unlock sequence */
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
/* Check if unlock was successful */
if (FLASH->CR & FLASH_CR_LOCK)
return FALSE;
return TRUE;
}
/**
* @brief Lock the flash memory for write access.
*/
#define flashLock() { FLASH->CR |= FLASH_CR_LOCK; }
int flashSectorErase(flashsector_t sector)
{
/* Unlock flash for write access */
if(flashUnlock() == FALSE)
return FLASH_RETURN_NO_PERMISSION;
/* Wait for any busy flags. */
flashWaitWhileBusy();
/* Setup parallelism before any program/erase */
FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
FLASH->CR |= FLASH_CR_PSIZE_VALUE;
/* Start deletion of sector.
* SNB(3:1) is defined as:
* 0000 sector 0
* 0001 sector 1
* ...
* 1011 sector 11
* others not allowed */
FLASH->CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3);
if (sector & 0x1) FLASH->CR |= FLASH_CR_SNB_0;
if (sector & 0x2) FLASH->CR |= FLASH_CR_SNB_1;
if (sector & 0x4) FLASH->CR |= FLASH_CR_SNB_2;
if (sector & 0x8) FLASH->CR |= FLASH_CR_SNB_3;
FLASH->CR |= FLASH_CR_SER;
FLASH->CR |= FLASH_CR_STRT;
/* Wait until it's finished. */
flashWaitWhileBusy();
/* Sector erase flag does not clear automatically. */
FLASH->CR &= ~FLASH_CR_SER;
/* Lock flash again */
flashLock();
/* Check deleted sector for errors */
if (flashIsErased(flashSectorBegin(sector), flashSectorSize(sector)) == FALSE)
return FLASH_RETURN_BAD_FLASH; /* Sector is not empty despite the erase cycle! */
/* Successfully deleted sector */
return FLASH_RETURN_SUCCESS;
}
int flashErase(flashaddr_t address, size_t size)
{
while (size > 0)
{
flashsector_t sector = flashSectorAt(address);
int err = flashSectorErase(sector);
if (err != FLASH_RETURN_SUCCESS)
return err;
address = flashSectorEnd(sector);
size_t sector_size = flashSectorSize(sector);
if (sector_size >= size)
break;
else
size -= sector_size;
}
return FLASH_RETURN_SUCCESS;
}
bool flashIsErased(flashaddr_t address, size_t size)
{
/* Check for default set bits in the flash memory
* For efficiency, compare flashdata_t values as much as possible,
* then, fallback to byte per byte comparison. */
while (size >= sizeof(flashdata_t))
{
if (*(volatile flashdata_t*)address != (flashdata_t)(-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
return FALSE;
address += sizeof(flashdata_t);
size -= sizeof(flashdata_t);
}
while (size > 0)
{
if (*(char*)address != 0xff)
return FALSE;
++address;
--size;
}
return TRUE;
}
bool flashCompare(flashaddr_t address, const char* buffer, size_t size)
{
/* For efficiency, compare flashdata_t values as much as possible,
* then, fallback to byte per byte comparison. */
while (size >= sizeof(flashdata_t))
{
if (*(volatile flashdata_t*)address != *(flashdata_t*)buffer)
return FALSE;
address += sizeof(flashdata_t);
buffer += sizeof(flashdata_t);
size -= sizeof(flashdata_t);
}
while (size > 0)
{
if (*(volatile char*)address != *buffer)
return FALSE;
++address;
++buffer;
--size;
}
return TRUE;
}
int flashRead(flashaddr_t address, char* buffer, size_t size)
{
memcpy(buffer, (char*)address, size);
return FLASH_RETURN_SUCCESS;
}
static void flashWriteData(flashaddr_t address, const flashdata_t data)
{
/* Enter flash programming mode */
FLASH->CR |= FLASH_CR_PG;
/* Write the data */
*(flashdata_t*)address = data;
/* Wait for completion */
flashWaitWhileBusy();
/* Exit flash programming mode */
FLASH->CR &= ~FLASH_CR_PG;
}
int flashWrite(flashaddr_t address, const char* buffer, size_t size)
{
/* Unlock flash for write access */
if(flashUnlock() == FALSE)
return FLASH_RETURN_NO_PERMISSION;
/* Wait for any busy flags */
flashWaitWhileBusy();
/* Setup parallelism before any program/erase */
FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
FLASH->CR |= FLASH_CR_PSIZE_VALUE;
/* Check if the flash address is correctly aligned */
size_t alignOffset = address % sizeof(flashdata_t);
if (alignOffset != 0)
{
/* Not aligned, thus we have to read the data in flash already present
* and update them with buffer's data */
/* Align the flash address correctly */
flashaddr_t alignedFlashAddress = address - alignOffset;
/* Read already present data */
flashdata_t tmp = *(volatile flashdata_t*)alignedFlashAddress;
/* Compute how much bytes one must update in the data read */
size_t chunkSize = sizeof(flashdata_t) - alignOffset;
if (chunkSize > size)
chunkSize = size; // this happens when both address and address + size are not aligned
/* Update the read data with buffer's data */
memcpy((char*)&tmp + alignOffset, buffer, chunkSize);
/* Write the new data in flash */
flashWriteData(alignedFlashAddress, tmp);
/* Advance */
address += chunkSize;
buffer += chunkSize;
size -= chunkSize;
}
/* Now, address is correctly aligned. One can copy data directly from
* buffer's data to flash memory until the size of the data remaining to be
* copied requires special treatment. */
while (size >= sizeof(flashdata_t))
{
flashWriteData(address, *(const flashdata_t*)buffer);
address += sizeof(flashdata_t);
buffer += sizeof(flashdata_t);
size -= sizeof(flashdata_t);
}
/* Now, address is correctly aligned, but the remaining data are to
* small to fill a entier flashdata_t. Thus, one must read data already
* in flash and update them with buffer's data before writing an entire
* flashdata_t to flash memory. */
if (size > 0)
{
flashdata_t tmp = *(volatile flashdata_t*)address;
memcpy(&tmp, buffer, size);
flashWriteData(address, tmp);
}
/* Lock flash again */
flashLock();
return FLASH_RETURN_SUCCESS;
}
/**
* Flash driver
* The driver code origin is
* https://github.com/mabl/ARMCM3-STM32F107-BOOTLOADER/tree/master/ARMCM3-STM32F107-BOOTLOADER/flash
* https://github.com/tegesoft/flash-stm32f407/tree/master/flash
*/
#include "flash.h"
#include <string.h>
/* TODO: The flash driver needs to be dynamically defined based on MCU. */
size_t flashSectorSize(flashsector_t sector)
{
if (sector <= 3)
return 16 * 1024;
else if (sector == 4)
return 64 * 1024;
else if (sector >= 5 && sector < FLASH_SECTOR_COUNT)
return 128 * 1024;
return 0;
}
flashaddr_t flashSectorBegin(flashsector_t sector)
{
flashaddr_t address = FLASH_BASE;
chDbgAssert(sector < FLASH_SECTOR_COUNT, "Invalid flash sector index");
while (sector > 0)
{
--sector;
address += flashSectorSize(sector);
}
return address;
}
flashaddr_t flashSectorEnd(flashsector_t sector)
{
return flashSectorBegin(sector + 1);
}
flashsector_t flashSectorAt(flashaddr_t address)
{
flashsector_t sector = 0;
while (address >= flashSectorEnd(sector))
++sector;
return sector;
}
/**
* @brief Wait for the flash operation to finish.
*/
#define flashWaitWhileBusy() { while (FLASH->SR & FLASH_SR_BSY) {} }
/**
* @brief Unlock the flash memory for write access.
* @return TRUE Unlock was successful.
* @return FALSE Unlock failed.
*/
static bool flashUnlock(void)
{
/* Check if unlock is really needed */
if (!(FLASH->CR & FLASH_CR_LOCK))
return TRUE;
/* Write magic unlock sequence */
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
/* Check if unlock was successful */
if (FLASH->CR & FLASH_CR_LOCK)
return FALSE;
return TRUE;
}
/**
* @brief Lock the flash memory for write access.
*/
#define flashLock() { FLASH->CR |= FLASH_CR_LOCK; }
int flashSectorErase(flashsector_t sector)
{
/* Unlock flash for write access */
if(flashUnlock() == FALSE)
return FLASH_RETURN_NO_PERMISSION;
/* Wait for any busy flags. */
flashWaitWhileBusy();
/* Setup parallelism before any program/erase */
FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
FLASH->CR |= FLASH_CR_PSIZE_VALUE;
/* Start deletion of sector.
* SNB(3:1) is defined as:
* 0000 sector 0
* 0001 sector 1
* ...
* 1011 sector 11
* others not allowed */
FLASH->CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3);
if (sector & 0x1) FLASH->CR |= FLASH_CR_SNB_0;
if (sector & 0x2) FLASH->CR |= FLASH_CR_SNB_1;
if (sector & 0x4) FLASH->CR |= FLASH_CR_SNB_2;
if (sector & 0x8) FLASH->CR |= FLASH_CR_SNB_3;
FLASH->CR |= FLASH_CR_SER;
FLASH->CR |= FLASH_CR_STRT;
/* Wait until it's finished. */
flashWaitWhileBusy();
/* Sector erase flag does not clear automatically. */
FLASH->CR &= ~FLASH_CR_SER;
/* Lock flash again */
flashLock();
/* Check deleted sector for errors */
if (flashIsErased(flashSectorBegin(sector), flashSectorSize(sector)) == FALSE)
return FLASH_RETURN_BAD_FLASH; /* Sector is not empty despite the erase cycle! */
/* Successfully deleted sector */
return FLASH_RETURN_SUCCESS;
}
int flashErase(flashaddr_t address, size_t size)
{
while (size > 0)
{
flashsector_t sector = flashSectorAt(address);
int err = flashSectorErase(sector);
if (err != FLASH_RETURN_SUCCESS)
return err;
address = flashSectorEnd(sector);
size_t sector_size = flashSectorSize(sector);
if (sector_size >= size)
break;
else
size -= sector_size;
}
return FLASH_RETURN_SUCCESS;
}
bool flashIsErased(flashaddr_t address, size_t size)
{
/* Check for default set bits in the flash memory
* For efficiency, compare flashdata_t values as much as possible,
* then, fallback to byte per byte comparison. */
while (size >= sizeof(flashdata_t))
{
if (*(volatile flashdata_t*)address != (flashdata_t)(-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
return FALSE;
address += sizeof(flashdata_t);
size -= sizeof(flashdata_t);
}
while (size > 0)
{
if (*(char*)address != 0xff)
return FALSE;
++address;
--size;
}
return TRUE;
}
bool flashCompare(flashaddr_t address, const char* buffer, size_t size)
{
/* For efficiency, compare flashdata_t values as much as possible,
* then, fallback to byte per byte comparison. */
while (size >= sizeof(flashdata_t))
{
if (*(volatile flashdata_t*)address != *(flashdata_t*)buffer)
return FALSE;
address += sizeof(flashdata_t);
buffer += sizeof(flashdata_t);
size -= sizeof(flashdata_t);
}
while (size > 0)
{
if (*(volatile char*)address != *buffer)
return FALSE;
++address;
++buffer;
--size;
}
return TRUE;
}
int flashRead(flashaddr_t address, char* buffer, size_t size)
{
memcpy(buffer, (char*)address, size);
return FLASH_RETURN_SUCCESS;
}
static void flashWriteData(flashaddr_t address, const flashdata_t data)
{
/* Enter flash programming mode */
FLASH->CR |= FLASH_CR_PG;
/* Write the data */
*(flashdata_t*)address = data;
/* Wait for completion */
flashWaitWhileBusy();
/* Exit flash programming mode */
FLASH->CR &= ~FLASH_CR_PG;
}
int flashWrite(flashaddr_t address, const char* buffer, size_t size)
{
/* Unlock flash for write access */
if(flashUnlock() == FALSE)
return FLASH_RETURN_NO_PERMISSION;
/* Wait for any busy flags */
flashWaitWhileBusy();
/* Setup parallelism before any program/erase */
FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
FLASH->CR |= FLASH_CR_PSIZE_VALUE;
/* Check if the flash address is correctly aligned */
size_t alignOffset = address % sizeof(flashdata_t);
if (alignOffset != 0)
{
/* Not aligned, thus we have to read the data in flash already present
* and update them with buffer's data */
/* Align the flash address correctly */
flashaddr_t alignedFlashAddress = address - alignOffset;
/* Read already present data */
flashdata_t tmp = *(volatile flashdata_t*)alignedFlashAddress;
/* Compute how much bytes one must update in the data read */
size_t chunkSize = sizeof(flashdata_t) - alignOffset;
if (chunkSize > size)
chunkSize = size; // this happens when both address and address + size are not aligned
/* Update the read data with buffer's data */
memcpy((char*)&tmp + alignOffset, buffer, chunkSize);
/* Write the new data in flash */
flashWriteData(alignedFlashAddress, tmp);
/* Advance */
address += chunkSize;
buffer += chunkSize;
size -= chunkSize;
}
/* Now, address is correctly aligned. One can copy data directly from
* buffer's data to flash memory until the size of the data remaining to be
* copied requires special treatment. */
while (size >= sizeof(flashdata_t))
{
flashWriteData(address, *(const flashdata_t*)buffer);
address += sizeof(flashdata_t);
buffer += sizeof(flashdata_t);
size -= sizeof(flashdata_t);
}
/* Now, address is correctly aligned, but the remaining data are to
* small to fill a entier flashdata_t. Thus, one must read data already
* in flash and update them with buffer's data before writing an entire
* flashdata_t to flash memory. */
if (size > 0)
{
flashdata_t tmp = *(volatile flashdata_t*)address;
memcpy(&tmp, buffer, size);
flashWriteData(address, tmp);
}
/* Lock flash again */
flashLock();
return FLASH_RETURN_SUCCESS;
}

Wyświetl plik

@ -1,177 +1,178 @@
/**
* Flash driver
* The driver code origin is
* https://github.com/mabl/ARMCM3-STM32F107-BOOTLOADER/tree/master/ARMCM3-STM32F107-BOOTLOADER/flash
* https://github.com/tegesoft/flash-stm32f407/tree/master/flash
*/
#ifndef FLASH_H
#define FLASH_H
#include <ch.h>
#include <hal.h>
#include <stdint.h>
/**
* @brief Number of sectors in the flash memory.
*/
#if !defined(FLASH_SECTOR_COUNT) || defined(__DOXYGEN__)
#define FLASH_SECTOR_COUNT 12
#endif
/* Error codes */
/** @brief Flash operation successful */
#define FLASH_RETURN_SUCCESS TRUE
/** @brief Flash operation error because of denied access, corrupted memory.*/
#define FLASH_RETURN_NO_PERMISSION -1
/** @brief Flash operation error because of bad flash, corrupted memory */
#define FLASH_RETURN_BAD_FLASH -11
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Maximum program/erase parallelism
*
* FLASH_CR_PSIZE_MASK is the mask to configure the parallelism value.
* FLASH_CR_PSIZE_VALUE is the parallelism value suitable for the voltage range.
*
* PSIZE(1:0) is defined as:
* 00 to program 8 bits per step
* 01 to program 16 bits per step
* 10 to program 32 bits per step
* 11 to program 64 bits per step
*/
// Warning, flashdata_t must be unsigned!!!
#if defined(STM32F4XX) || defined(__DOXYGEN__)
#define FLASH_CR_PSIZE_MASK FLASH_CR_PSIZE_0 | FLASH_CR_PSIZE_1
#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__)
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_1
typedef uint32_t flashdata_t;
#elif (STM32_VDD >= 240) && (STM32_VDD < 270)
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_0
typedef uint16_t flashdata_t;
#elif (STM32_VDD >= 210) && (STM32_VDD < 240)
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_0
typedef uint16_t flashdata_t;
#elif (STM32_VDD >= 180) && (STM32_VDD < 210)
#define FLASH_CR_PSIZE_VALUE ((uint32_t)0x00000000)
typedef uint8_t flashdata_t;
#else
#error "invalid VDD voltage specified"
#endif
#endif /* defined(STM32F4XX) */
/** @brief Address in the flash memory */
typedef uintptr_t flashaddr_t;
/** @brief Index of a sector */
typedef uint8_t flashsector_t;
/**
* @brief Get the size of @p sector.
* @return @p sector size in bytes.
*/
size_t flashSectorSize(flashsector_t sector);
/**
* @brief Get the beginning address of @p sector.
* @param sector Sector to retrieve the beginning address of.
* @return First address (inclusive) of @p sector.
*/
flashaddr_t flashSectorBegin(flashsector_t sector);
/**
* @brief Get the end address of @p sector.
* @param sector Sector to retrieve the end address of.
* @return End address (exclusive) of @p sector (i.e. beginning address of the next sector).
*/
flashaddr_t flashSectorEnd(flashsector_t sector);
/**
* @brief Get the sector containing @p address.
* @warning @p address must be in the flash addresses range.
* @param address Address to be searched for.
* @return Sector containing @p address.
*/
flashsector_t flashSectorAt(flashaddr_t address);
/**
* @brief Erase the flash @p sector.
* @details The sector is checked for errors after erase.
* @note The sector is deleted regardless of its current state.
*
* @param sector Sector which is going to be erased.
* @return FLASH_RETURN_SUCCESS No error erasing the sector.
* @return FLASH_RETURN_BAD_FLASH Flash cell error.
* @return FLASH_RETURN_NO_PERMISSION Access denied.
*/
int flashSectorErase(flashsector_t sector);
/**
* @brief Erase the sectors containing the span of @p size bytes starting at @p address.
*
* @warning If @p address doesn't match the beginning of a sector, the
* data contained between the beginning of the sector and @p address will
* be erased too. The same applies for data contained at @p address + @p size
* up to the end of the sector.
*
* @param address Starting address of the span in flash memory.
* @param size Size of the span in bytes.
* @return FLASH_RETURN_SUCCESS No error erasing the flash memory.
* @return FLASH_RETURN_BAD_FLASH Flash cell error.
* @return FLASH_RETURN_NO_PERMISSION Access denied.
*/
int flashErase(flashaddr_t address, size_t size);
/**
* @brief Check if the @p size bytes of flash memory starting at @p address are erased.
* @note If the memory is erased, one can write data into it safely.
* @param address First address in flash memory to be checked.
* @param size Size of the memory space to be checked in bytes.
* @return TRUE Memory is already erased.
* @return FALSE Memory is not erased.
*/
bool flashIsErased(flashaddr_t address, size_t size);
/**
* @brief Check if the data in @p buffer are identical to the one in flash memory.
* @param address First address in flash memory to be checked.
* @param buffer Buffer containing the data to compare.
* @param size Size of @p buffer in bytes.
* @return TRUE if the flash memory and the buffer contain identical data.
* @return FALSE if the flash memory and the buffer don't contain identical data.
*/
bool flashCompare(flashaddr_t address, const char* buffer, size_t size);
/**
* @brief Copy data from the flash memory to a @p buffer.
* @warning The @p buffer must be at least @p size bytes long.
* @param address First address of the flash memory to be copied.
* @param buffer Buffer to copy to.
* @param size Size of the data to be copied in bytes.
* @return FLASH_RETURN_SUCCESS if successfully copied.
*/
int flashRead(flashaddr_t address, char* buffer, size_t size);
/**
* @brief Copy data from a @p buffer to the flash memory.
* @warning The flash memory area receiving the data must be erased.
* @warning The @p buffer must be at least @p size bytes long.
* @param address First address in the flash memory where to copy the data to.
* @param buffer Buffer containing the data to copy.
* @param size Size of the data to be copied in bytes.
* @return FLASH_RETURN_SUCCESS No error.
* @return FLASH_RETURN_NO_PERMISSION Access denied.
*/
int flashWrite(flashaddr_t address, const char* buffer, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* FLASH_H */
/**
* Flash driver
* The driver code origin is
* https://github.com/mabl/ARMCM3-STM32F107-BOOTLOADER/tree/master/ARMCM3-STM32F107-BOOTLOADER/flash
* https://github.com/tegesoft/flash-stm32f407/tree/master/flash
*/
#ifndef FLASH_H
#define FLASH_H
#include <ch.h>
#include <hal.h>
#include <stdint.h>
/**
* @brief Number of sectors in the flash memory.
* TODO: The flash driver needs to be dynamically defined based on MCU.
*/
#if !defined(FLASH_SECTOR_COUNT) || defined(__DOXYGEN__)
#define FLASH_SECTOR_COUNT 16
#endif
/* Error codes */
/** @brief Flash operation successful */
#define FLASH_RETURN_SUCCESS TRUE
/** @brief Flash operation error because of denied access, corrupted memory.*/
#define FLASH_RETURN_NO_PERMISSION -1
/** @brief Flash operation error because of bad flash, corrupted memory */
#define FLASH_RETURN_BAD_FLASH -11
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Maximum program/erase parallelism
*
* FLASH_CR_PSIZE_MASK is the mask to configure the parallelism value.
* FLASH_CR_PSIZE_VALUE is the parallelism value suitable for the voltage range.
*
* PSIZE(1:0) is defined as:
* 00 to program 8 bits per step
* 01 to program 16 bits per step
* 10 to program 32 bits per step
* 11 to program 64 bits per step
*/
// Warning, flashdata_t must be unsigned!!!
#if defined(STM32F4XX) || defined(__DOXYGEN__)
#define FLASH_CR_PSIZE_MASK FLASH_CR_PSIZE_0 | FLASH_CR_PSIZE_1
#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__)
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_1
typedef uint32_t flashdata_t;
#elif (STM32_VDD >= 240) && (STM32_VDD < 270)
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_0
typedef uint16_t flashdata_t;
#elif (STM32_VDD >= 210) && (STM32_VDD < 240)
#define FLASH_CR_PSIZE_VALUE FLASH_CR_PSIZE_0
typedef uint16_t flashdata_t;
#elif (STM32_VDD >= 180) && (STM32_VDD < 210)
#define FLASH_CR_PSIZE_VALUE ((uint32_t)0x00000000)
typedef uint8_t flashdata_t;
#else
#error "invalid VDD voltage specified"
#endif
#endif /* defined(STM32F4XX) */
/** @brief Address in the flash memory */
typedef uintptr_t flashaddr_t;
/** @brief Index of a sector */
typedef uint8_t flashsector_t;
/**
* @brief Get the size of @p sector.
* @return @p sector size in bytes.
*/
size_t flashSectorSize(flashsector_t sector);
/**
* @brief Get the beginning address of @p sector.
* @param sector Sector to retrieve the beginning address of.
* @return First address (inclusive) of @p sector.
*/
flashaddr_t flashSectorBegin(flashsector_t sector);
/**
* @brief Get the end address of @p sector.
* @param sector Sector to retrieve the end address of.
* @return End address (exclusive) of @p sector (i.e. beginning address of the next sector).
*/
flashaddr_t flashSectorEnd(flashsector_t sector);
/**
* @brief Get the sector containing @p address.
* @warning @p address must be in the flash addresses range.
* @param address Address to be searched for.
* @return Sector containing @p address.
*/
flashsector_t flashSectorAt(flashaddr_t address);
/**
* @brief Erase the flash @p sector.
* @details The sector is checked for errors after erase.
* @note The sector is deleted regardless of its current state.
*
* @param sector Sector which is going to be erased.
* @return FLASH_RETURN_SUCCESS No error erasing the sector.
* @return FLASH_RETURN_BAD_FLASH Flash cell error.
* @return FLASH_RETURN_NO_PERMISSION Access denied.
*/
int flashSectorErase(flashsector_t sector);
/**
* @brief Erase the sectors containing the span of @p size bytes starting at @p address.
*
* @warning If @p address doesn't match the beginning of a sector, the
* data contained between the beginning of the sector and @p address will
* be erased too. The same applies for data contained at @p address + @p size
* up to the end of the sector.
*
* @param address Starting address of the span in flash memory.
* @param size Size of the span in bytes.
* @return FLASH_RETURN_SUCCESS No error erasing the flash memory.
* @return FLASH_RETURN_BAD_FLASH Flash cell error.
* @return FLASH_RETURN_NO_PERMISSION Access denied.
*/
int flashErase(flashaddr_t address, size_t size);
/**
* @brief Check if the @p size bytes of flash memory starting at @p address are erased.
* @note If the memory is erased, one can write data into it safely.
* @param address First address in flash memory to be checked.
* @param size Size of the memory space to be checked in bytes.
* @return TRUE Memory is already erased.
* @return FALSE Memory is not erased.
*/
bool flashIsErased(flashaddr_t address, size_t size);
/**
* @brief Check if the data in @p buffer are identical to the one in flash memory.
* @param address First address in flash memory to be checked.
* @param buffer Buffer containing the data to compare.
* @param size Size of @p buffer in bytes.
* @return TRUE if the flash memory and the buffer contain identical data.
* @return FALSE if the flash memory and the buffer don't contain identical data.
*/
bool flashCompare(flashaddr_t address, const char* buffer, size_t size);
/**
* @brief Copy data from the flash memory to a @p buffer.
* @warning The @p buffer must be at least @p size bytes long.
* @param address First address of the flash memory to be copied.
* @param buffer Buffer to copy to.
* @param size Size of the data to be copied in bytes.
* @return FLASH_RETURN_SUCCESS if successfully copied.
*/
int flashRead(flashaddr_t address, char* buffer, size_t size);
/**
* @brief Copy data from a @p buffer to the flash memory.
* @warning The flash memory area receiving the data must be erased.
* @warning The @p buffer must be at least @p size bytes long.
* @param address First address in the flash memory where to copy the data to.
* @param buffer Buffer containing the data to copy.
* @param size Size of the data to be copied in bytes.
* @return FLASH_RETURN_SUCCESS No error.
* @return FLASH_RETURN_NO_PERMISSION Access denied.
*/
int flashWrite(flashaddr_t address, const char* buffer, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* FLASH_H */

Wyświetl plik

@ -4,8 +4,11 @@
dataPoint_t* flash_getLogBuffer(uint16_t id)
{
uint32_t addr = LOG_FLASH_ADDR + LOG_SECTOR_ID(id) * LOG_SECTOR_SIZE + LOG_POS_IN_SECTOR(id) * sizeof(dataPoint_t);
if(addr >= LOG_FLASH_ADDR && addr <= LOG_FLASH_ADDR+LOG_FLASH_SIZE-sizeof(dataPoint_t))
uint32_t addr = LOG_FLASH_ADDR
+ (LOG_SECTOR_ID(id) * LOG_SECTOR_SIZE)
+ (LOG_POS_IN_SECTOR(id) * sizeof(dataPoint_t));
if(addr >= LOG_FLASH_ADDR
&& addr <= (LOG_FLASH_ADDR + LOG_FLASH_SIZE - sizeof(dataPoint_t)))
return (dataPoint_t*)addr;
else
return NULL; // Outside of memory address allocation
@ -95,7 +98,7 @@ void flash_writeLogDataPoint(dataPoint_t* tp)
{
// Get address to write on
dataPoint_t* address = flash_getNextFreeLogAddress();
if(address == NULL) // Memory completly used, erase oldest data
if(address == NULL) // Memory completely used, erase oldest data
{
flash_eraseOldestLogData();
address = flash_getNextFreeLogAddress();

Wyświetl plik

@ -543,6 +543,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
AFSKDemodDriver *myDriver = arg;
packet_svc_t *myHandler = myDriver->packet_handler;
radio_unit_t radio = myHandler->radio;
tprio_t decoder_idle_priority;
/* No active packet object. */
myHandler->active_packet_object = NULL;
@ -577,7 +578,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
}
/* Save the priority that calling thread gave us. */
tprio_t decoder_idle_priority = chThdGetPriorityX();
decoder_idle_priority = chThdGetPriorityX();
/* Setup LED for decoder blinker. */
pktLLDradioConfigIndicator(radio, PKT_INDICATOR_DECODE);
@ -608,7 +609,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
pktAddEventFlags(myDriver, DEC_CLOSE_EXEC);
pktReleaseAFSKDecoder(myDriver);
myDriver->decoder_state = DECODER_TERMINATED;
pktWriteGPIOline(LINE_DECODER_LED, PAL_LOW);
pktLLDradioUpdateIndicator(radio, PKT_INDICATOR_DECODE, PAL_LOW);
chThdExit(MSG_OK);
/* Something went wrong if we arrive here. */
chSysHalt("ThdExit");
@ -670,18 +671,24 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/* Check if prior packet buffer released. */
chDbgCheck(myHandler->active_packet_object == NULL);
/* Get a packet buffer. */
/*
* Get a reference to the packet management FIFO.
* The factory reference count is increased when found.
*/
dyn_objects_fifo_t *pkt_fifo =
chFactoryFindObjectsFIFO(myHandler->pbuff_name);
chDbgAssert(pkt_fifo != NULL, "unable to find packet fifo");
/* The factory reference count is increased. */
objects_fifo_t *pkt_buffer_pool = chFactoryGetObjectsFIFO(pkt_fifo);
chDbgAssert(pkt_buffer_pool != NULL, "no packet fifo list");
/*
* Packet management FIFO found.
* Now get reference to inner FIFO allocator.
*/
objects_fifo_t *pkt_object_pool = chFactoryGetObjectsFIFO(pkt_fifo);
chDbgAssert(pkt_object_pool != NULL, "no packet fifo list");
/* Get a buffer and have it initialized ready for use. */
/* Get a packet management object and assign a data buffer. */
pkt_data_object_t *myPktBuffer = pktTakeDataBuffer(myHandler,
pkt_buffer_pool,
pkt_object_pool,
TIME_MS2I(100));
#if AFSK_DEBUG_TYPE == AFSK_PWM_DATA_CAPTURE_DEBUG
char buf[80];
@ -690,9 +697,9 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
pktWrite( (uint8_t *)buf, out);
#endif
/* If no buffer is available the handler pointer is also set to NULL. */
/* If no management object or data buffer is available get NULL. */
if(myPktBuffer == NULL) {
/* Decrease ref count on AX25 FIFO. */
/* Decrease ref count on packet management object FIFO. */
chFactoryReleaseObjectsFIFO(pkt_fifo);
pktAddEventFlags(myHandler, EVT_PKT_NO_BUFFER);
myDriver->active_demod_stream->status |= STA_PKT_NO_BUFFER;
@ -702,7 +709,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/* Increase thread priority. */
(void)chThdSetPriority(DECODER_RUN_PRIORITY);
decoder_idle_priority = chThdSetPriority(DECODER_RUN_PRIORITY);
/* Enable processing of incoming PWM stream. */
myDriver->decoder_state = DECODER_ACTIVE;
@ -745,7 +752,10 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/* Timeout calculated as SYMBOL time x 8 x 20. */
if(n != sizeof(packed_pwm_counts_t)) {
/* PWM stream wait timeout. */
/*
* PWM stream wait timeout.
* No in-band close or abort in stream.
*/
pktAddEventFlags(myHandler, EVT_PWM_STREAM_TIMEOUT);
myFIFO->status |= STA_PWM_STREAM_TIMEOUT;
myDriver->decoder_state = DECODER_RESET;
@ -819,7 +829,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/* This is a debug error.
* CCA is validated but a PWM is still active.
* The PWM side has already posted a PWM_FIFO_REMNANT event.
* The PWM side has already posted a PWM_FIFO_ORDER event.
*/
case PWM_TERM_QUEUE_ERR:
@ -912,10 +922,34 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
myDriver->decoder_state = DECODER_DISPATCH;
continue; /* From this case. */
}
} /* End switch. */
} /* End switch on frame_state. */
break; /* Keep GCC 7 happy. */
} /* End case DECODER_ACTIVE. */
case DECODER_DISPATCH: {
if(myHandler->active_packet_object != NULL) {
/*
* Indicate AFSK decode done.
* PWM handler will terminate capture session if still active.
*/
myDriver->active_demod_stream->status |= STA_AFSK_DECODE_DONE;
/* Copy latest status into packet buffer object. */
myHandler->active_packet_object->status =
myDriver->active_demod_stream->status;
/* Set AX25 status and dispatch the packet buffer object. */
pktDispatchReceivedBuffer(myHandler->active_packet_object);
/* Packet object has been handed over. Remove our reference. */
myHandler->active_packet_object = NULL;
} /* Active packet object != NULL. */
/* Release PWM buffers and reset decoder in RESET state. */
myDriver->decoder_state = DECODER_RESET;
break;
} /* End case DECODER_DISPATCH. */
/*
* RESET readies the decoder for the next session.
* It frees any held buffers/objects.
@ -955,10 +989,10 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
#if USE_CCM_BASED_PWM_HEAP == TRUE
pktAssertCCMdynamicCheck(myHandler->active_packet_object->buffer);
#endif
/* Free the packet buffer referenced in the packet object. */
/* Free the data buffer referenced in the packet object. */
chHeapFree(myHandler->active_packet_object->buffer);
#endif
/* Release the AX25 receive packet buffer management object. */
/* Release the receive packet buffer management object. */
objects_fifo_t *pkt_fifo =
chFactoryGetObjectsFIFO(myHandler->active_packet_object->pkt_factory);
@ -1020,30 +1054,6 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
myDriver->decoder_state = DECODER_IDLE;
break;
} /* End case DECODER_RESET. */
case DECODER_DISPATCH: {
if(myHandler->active_packet_object != NULL) {
/*
* Indicate AFSK decode done.
* PWM handler will terminate capture session if still active.
*/
myDriver->active_demod_stream->status |= STA_AFSK_DECODE_DONE;
/* Copy latest status into packet buffer object. */
myHandler->active_packet_object->status =
myDriver->active_demod_stream->status;
/* Set AX25 status and dispatch the packet buffer object. */
pktDispatchReceivedBuffer(myHandler->active_packet_object);
/* Packet object has been handed over. Remove our reference. */
myHandler->active_packet_object = NULL;
} /* Active packet object != NULL. */
/* Release PWM buffers and reset decoder in RESET state. */
myDriver->decoder_state = DECODER_RESET;
break;
} /* End case DECODER_DISPATCH. */
} /* End switch on decoder state. */
} /* End thread while(true). */
}

Wyświetl plik

@ -38,7 +38,7 @@
#define AFSK_DSP_QCORR_DECODE 1
#define AFSK_DSP_FCORR_DECODE 2 /* Currently under test. */
#define AFSK_DECODE_TYPE AFSK_DSP_QCORR_DECODE
#define AFSK_DECODE_TYPE AFSK_DSP_FCORR_DECODE
#if !defined(AFSK_DECODE_TYPE)
#error "AFSK decoder not specified"
#endif

Wyświetl plik

@ -427,7 +427,7 @@ void pktOpenPWMChannelI(ICUDriver *myICU, eventflags_t evt) {
* Shouldn't happen unless CCA has not triggered an EXTI trailing edge.
* For now just flag that an error condition happened.
*/
pktClosePWMchannelI(myICU, EVT_PWM_FIFO_REMNANT, PWM_TERM_QUEUE_ERR);
pktClosePWMchannelI(myICU, PWM_FIFO_ORDER, PWM_TERM_QUEUE_ERR);
return;
}
/* Normal CCA handling. */

Wyświetl plik

@ -381,53 +381,54 @@ extern "C" {
}
/**
* @brief Fetches a buffer from the packet buffer free pool.
* @brief Gets an sets up a packet management object.
* @notes Fetches a management object from the FIFO pool.
* @notes A packet buffer is then obtained and assigned to the object.
* @details This function is called from thread level to obtain a buffer
* to write AX25 data into.
*
* @param[in] handler pointer to a @p packet service object
* @param[in] fifo pointer to a @p objects FIFO
* @paream[in] timeout Allowable wait for a free buffer
* @paream[in] timeout Allowable wait for a free data buffer
*
* @return pointer to packet buffer object.
* @retval NULL if no buffer object available.
* @return pointer to packet management object.
* @retval NULL if no management object or buffer available.
*
* @api
*/
static inline pkt_data_object_t *pktTakeDataBuffer(packet_svc_t *handler,
objects_fifo_t *fifo,
sysinterval_t timeout) {
/* Get a management object from the FIFO pool. */
pkt_data_object_t *pkt_buffer = chFifoTakeObjectTimeout(fifo, timeout);
handler->active_packet_object = pkt_buffer;
if(pkt_buffer != NULL) {
/*
* Packet buffer available.
* Packet management object available.
* Initialize the object fields.
*/
//handler->active_packet_object = pkt_buffer;
/* Initialize the object fields. */
pkt_buffer->handler = handler;
pkt_buffer->status = EVT_STATUS_CLEAR;
pkt_buffer->packet_size = 0;
pkt_buffer->buffer_size = PKT_RX_BUFFER_SIZE;
pkt_buffer->cb_func = handler->usr_callback;
/* Save the pointer to the packet factory for use when releasing object. */
/* Save the pointer to the object factory for use when releasing object. */
pkt_buffer->pkt_factory = handler->the_packet_fifo;
#if USE_CCM_HEAP_RX_BUFFERS == TRUE
extern memory_heap_t *ccm_heap;
pkt_buffer->buffer = chHeapAlloc(ccm_heap, PKT_RX_BUFFER_SIZE);
if(pkt_buffer->buffer == NULL) {
/* No heap available. */
/* Return packet buffer object to free list. */
/* No heap available for data buffer. */
/* Return management object to free list. */
chFifoReturnObject(fifo, (pkt_data_object_t *)pkt_buffer);
/*
* Decrease FIFO reference counter (increased by decoder).
* FIFO will be destroyed when all references are released.
*/
chFactoryReleaseObjectsFIFO(pkt_buffer->pkt_factory);
/*chFactoryReleaseObjectsFIFO(pkt_buffer->pkt_factory);*/
pkt_buffer = NULL;
}
#endif

Wyświetl plik

@ -81,7 +81,7 @@
#define EVT_PWM_BUFFER_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 15)
#define EVT_RAD_STREAM_OPEN EVENT_MASK(EVT_PRIORITY_BASE + 16)
#define EVT_PWM_FIFO_REMNANT EVENT_MASK(EVT_PRIORITY_BASE + 17)
#define PWM_FIFO_ORDER EVENT_MASK(EVT_PRIORITY_BASE + 17)
#define EVT_RAD_STREAM_CLOSE EVENT_MASK(EVT_PRIORITY_BASE + 18)
//#define STA_PKT_INVALID_FRAME EVENT_MASK(EVT_PRIORITY_BASE + 19)