This really depends on what it needs the FLASH storage for, frequency of access, storage size, board space, complexity, etc. Knowing what wifi chip you're considering would help but I would probably just stick a small SPI flash chip on there - or at least a footprint for it on a first prototype.
Al_Brown
Posts
-
Oi embedded folks -
Egochating?Yes, but didn't you know that Matthew invented all those as well?
-
code reviewtrønderen wrote:
According to him, there is one, single way of coding an infinite loop, that is immediately recognized by every programmer in the world, and that is 'while (1)'
(Changed the 0 to 1 per your earlier replies) Lint may disagree with his assertion that while(1) {} is the only and preferred way to write a loop - I have had it prefer the for(;;) construct and both are versions that are easily recognised. I wouldn't personally be a fan of "#define ever ;;" as it "feels" fragile both in requiring the definition be included consistently and the risk someone may one day want to name a variable or function as that. Would be something for an interesting private discussion rather than "show and tell" at a scrum meeting, however!
-
a generic question about database tableEddy Vluggen wrote:
That's why I stopped visiting the hospital. I don't wont to die by VB6
You'll be fine if you believe in reincarnation...
On Error Resume Next Life
-
Christmas memeExactly!
-
Christmas memeI am not convinced that would stop most cats!
-
am I Being WatchedI would say coincidence and a good example of selection bias. I was also recently flooded with DeWalt adverts but didn't really give it a second thought. I hadn't discussed power tools with anyone or searched for them, etc. For you it stood out as you had been talking about them when they popped up, for me it was just another ad campaign. I would imagine there are 100 other adverts that you saw in the same time period that you ignored as just "par for the course" and not related to any discussions you'd had.
-
Outlook can be a PITA, but ...You should feel proud that it has taken so long for you to notice this! Those saying it's been around for years have, like myself, only have the benefit of making this mistake sooner.
-
I'm so overwhelmed. =/From a very quick scan the things that concern me with that code aren't whether reads are const or not. The number of "TODO", "BUG" and commented out lines imply that it hasn't been finished. May be suitable for what you need but having a clean codebase you can trust is far more important than whether it is fully optimised for language semantics.
-
Wow, but NASes have moved on since I last bought one...Very happy with my QNAP as well. Only note of caution is to make sure to keep the thing updated and turn off remote access features. There have been quite a few security issues over the last few years including ransomware attacks.
-
This is actually cleaned up!OK - it wasn't immediately clear that the bit mapping was constant at compile time. Personally, I'd still be inclined to do something like this but would want to confirm it was optimising as expected (which I'm sure you've done with the existing code):
// Data pin GPIO allocation - purely an example
const unsigned pin_d0 = 4;
const unsigned pin_d1 = 5;
const unsigned pin_d2 = 6;
const unsigned pin_d3 = 7;
const unsigned pin_d4 = 36;
const unsigned pin_d5 = 37;
const unsigned pin_d6 = 38;
const unsigned pin_d7 = 39;// Read our eight bit bus value from the appropriate GPIO pins
static uint8_t readInput(void)
{
// Add delay here// Read the hardware bus uint32\_t GPIOLow = gpio\_input\_get(); uint32\_t GPIOHigh = gpio\_input\_get\_high(); // Decode from GPIO to eight bit bus uint8\_t dataRead = 0; dataRead |= (((pin\_d0 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d0 & 31)) & 1) << 0; dataRead |= (((pin\_d1 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d1 & 31)) & 1) << 1; dataRead |= (((pin\_d2 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d2 & 31)) & 1) << 2; dataRead |= (((pin\_d3 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d3 & 31)) & 1) << 3; dataRead |= (((pin\_d4 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d4 & 31)) & 1) << 4; dataRead |= (((pin\_d5 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d5 & 31)) & 1) << 5; dataRead |= (((pin\_d6 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d6 & 31)) & 1) << 6; dataRead |= (((pin\_d7 > 31 ? GPIOHigh : GPIOLow) >> (pin\_d7 & 31)) & 1) << 7; return dataRead;
}
In practice, I would almost certainly encapsulate the individual lines as macros or as an inline function but it's probably clear enough what it's doing. Reads from both ports are kept in there - if a single hardware register read is really killing you then it could be eliminated. The delay aspect would still concern me. This is presumably reading from an external device (LCD?) and there will be a defined timing between initiating a read and the data being available. You will get away with your approach on a specific hardware platform but in future it could easily fall down if the clock speed changes or the external delays change. Dropping to assembler shouldn't be necessary - but your code shouldn't depend on how long it takes to do a dummy read. As an aside, the original code has instances of this:
if(pin_d1>31) {
b |= (((pins_h>>((pin_d1-32)&31))&1)<<1);
} else if(pin_d1>-1) {
b |= (((pins_l>>(pin_d1))&1)<<1);
}Sub
-
This is actually cleaned up!I realise you're not asking for suggestions but I would certainly be minded to simplify this, particularly if this is for general purpose use. If you're in a situation where this is for an embedded platform where the hardware configuration is fixed you should gain both better readability and performance if you can spare a little RAM. Something like this:
const int NUM_BUS_BITS = 8; // Dealing with an eight bit bus
const int NUM_GPIO_PINS = 40; // ESP32 has GPIOs 0 to 39// Last read state of the GPIO bus
static uint32_t sGPIOLow, sGPIOHigh;// Map data bus to GPIO bits
static struct
{
uint32_t* pSource; // Which GPIO variable to use
unsigned shift; // Shift to apply for this bit
} sDataMap[NUM_BUS_BITS];// Initialise mapping between input data bit and GPIO pin - call for each data bit prior to readInput()
static void mapInputPin(unsigned dataBit, unsigned gpioPin)
{
if (dataBit < NUM_BUS_BITS && gpioPin < NUM_GPIO_PINS)
{
sDataMap[dataBit].pSource = gpioPin >= 32 ? &sGPIOHigh : &sGPIOLow;
sDataMap[dataBit].shift = gpioPin & 31;
}
}// Read our eight bit bus value from the appropriate GPIO pins
static uint8_t readInput(void)
{
// Read the hardware bus (the need for 3x reads should be investigated)
sGPIOLow = gpio_input_get();
sGPIOLow = gpio_input_get();
sGPIOLow = gpio_input_get();
sGPIOHigh = gpio_input_get_high();// Decode from GPIO to eight bit bus uint8\_t dataRead = 0; dataRead |= (((\*sDataMap\[0\].pSource) >> sDataMap\[0\].shift) & 1) << 0; dataRead |= (((\*sDataMap\[1\].pSource) >> sDataMap\[1\].shift) & 1) << 1; dataRead |= (((\*sDataMap\[2\].pSource) >> sDataMap\[2\].shift) & 1) << 2; dataRead |= (((\*sDataMap\[3\].pSource) >> sDataMap\[3\].shift) & 1) << 3; dataRead |= (((\*sDataMap\[4\].pSource) >> sDataMap\[4\].shift) & 1) << 4; dataRead |= (((\*sDataMap\[5\].pSource) >> sDataMap\[5\].shift) & 1) << 5; dataRead |= (((\*sDataMap\[6\].pSource) >> sDataMap\[6\].shift) & 1) << 6; dataRead |= (((\*sDataMap\[7\].pSource) >> sDataMap\[7\].shift) & 1) << 7; return dataRead;
}
int main(void)
{
// Initialise mapping for GPIO allocation
// (Use defines or named constants for a real implementation)
mapInputPin(0, 4);
mapInputPin(1, 5);
mapInputPin(2, 6);
mapInputPin(3, 7);
mapInputPin(4, 36);
mapInputPin(5, 37);
mapInputPin(6, 38);
mapInputPin(7, 39);// Read input uint8\_t readData = readInput
-
Wah hey! I've got my second Covid jab date!Is there an online system where you are that you can log on and rearrange the location to somewhere more convenient? Did that for the wife when it was going to clash with a holiday and was able to choose a location a couple of miles away instead of the original place that was much farther away.
-
software, business analysis and proposalsMarc Clifton wrote:
You know how at Chinese restaurants someone has to make a joke by appending "in bed" to the fortune cookie? Read those "baseline logic" bullet points the same way.
I think if you added "in bed" to each of those bullet points you're going to end up with a very different business proposition.
-
FTP, FileZilla and/or Win10I had a similar problem logging into a system a week ago (from Windows 10) - the password kept being rejected. When I also was unable to log onto a database server I was getting even more concerned that someone had hacked in and reset passwords. Turned out to be something simple - Windows 10 had switched my keyboard to a US layout from my normal UK one. Both passwords contained punctuation characters which were being switched due to the change of layout.
-
Microsoft sneaks yet more ads into Windows 10 Creators UpdateThe link in the email newsletter appears to be broken - the News script redirects to http://I'm%20looking%20for%20examples%20of%20were%20auto-formatting%20like%20this%20would%20be%20A%20Bad%20Thing. Presumably this should be: Microsoft sneaks yet more ads into Windows 10 Creators Update[^]?
-
Game design questionI've certainly played games (e.g. Spacechem) where the stats are tracked separately as achievements to beat. For example, in that game you can construct a solution that uses very few "parts" but runs slowly and another solution that uses many parts but runs quickly. The number of parts you use and the time it runs for are both separate stats that are tracked independently. It's an approach I actually prefer - it takes the guesswork out of what constitutes an overall "score" and ultimately it boils down into individual high score tables rather than attempting to create one that may not be balanced in the eyes of the players.
-
Thats why i hate c++(from the code in your link)
void TfrmMain::GetDir()
{
TFileListBox * ListBox = new TFileListBox(this);
frmMain->InsertControl(ListBox);
AnsiString way = ListBox->Directory;
way=way+" audio";
way[way.Length()-5]=92;
dir=way;
way=way.SubString(0,way.Length()-6);
ListBox->Directory=way;
frmMain->RemoveControl(ListBox);
}If it's your code, I think you may want to learn a little more before complaining about C++. One thing you certainly should take into account is that C++ is not a managed language and constructing objects and never deleting them will lead to memory leaks.
-
The Code RepeaterNo - it's how he protects his job :)
-
Single Update Query for.....This is just theoretical, right....? You could do something like this:
UPDATE a SET name = (SELECT TOP 1 a2.name FROM a AS a2
WHERE a2.id * ((a.id & 1) * 2 - 1) > a.id * ((a.id & 1) * 2 - 1)
AND (a2.id ^ a.id) & 1 = 1
ORDER BY a2.id * ((a.id & 1) * 2 - 1))But then you're going into Hall Of Shame territory