Cutting pumpkins
Today I took pruning shears to work for the first time. After work at Herenboeren Usseler Es I helped cut and collect the pumpkins. The pruning
shears were actually a bit oversized until we got to the 'family pumpkin', so
called because of their size. This type of pumpkins were grown by Isabel
Duinisveld from pumpkin seeds that she bought from the Marina Di Chioggia
pumpkins in 2014. Isabel helped start Herenboeren Usseler Es last year.
Chapter 27 of ESP32-S3 Technical Reference Manual describes the hardware components and
registers that are used for the I²C bus. (On September 2, I wrote
before about I²C.) For accessing the registers from C, the include file
i2c_struct.h can be used. According to Table 4-3, one has to
cast the address 0x6000F000 to i2c_dev_t* to access the 'I2C
Controller 0' and the address 0x60029000 to access 'I2C Controller 1'. The
include file i2c_ll.h gives all kind of helper functions to access and modifiy the
registers. Section 27.5 describes how the different command registers have to
be used to send read and write I²C commands. It seems that the function
i2c_ll_master_write_cmd_reg can be used to set the commands. This
function uses a value of the type i2c_ll_hw_cmd_t, which can be used
to specify the various parts of the command. For examples how this function
can be called, see the files i2c.c and i2c_master.c.
Still life of the harvest
Below a still life of part of the
harvest that we received this morning from Herenboeren Usseler Es or what I took from the giveaway table where other
members can donate part of their harvest or where vegetables are harvested but
not given out because they are too small or left over from a previous issue.
The picture shows:
- A bag with some flour.
- Two fennels
- A sweet potato
- Two small pumpkins
- A red onion
- Two leeks
- Two (orange) pumpkins
- A courgette
- A red chicory (a cross between Belgian endive and Radicchio Rosso, I read somewhere)
While developing embedded software, you often have to deal with state machines,
to implement non-blocking behaviour. If for example, one of the tasks for your
embedded software is to read data from some UART and send it to another UART, you could have a function like:
void echo_infinite(UART *in, UART *out)
{
while (1)
{
while (!data_available(in))
{
// wait
}
char ch;
ch = read_byte(in);
while (!ready_for_sending(out))
{
// wait
}
write_byte(out, ch);
}
}
The above function will never terminate. That is no problem if that is the
only thing your device has to do, but totally not acceptable, if your device
has to do something else as well, for example, have a blinking LED. The
traditional solution is to use a state machine and call the function
implementing the state machine from the (never terminating) main loop. In case
there is just one such task, one can make use of static define variables for
the local variables. Otherwise, one has to define a struct for each such
task and pass this as an argument. (See the page Machine independent implementation of Cooperative Multi-threading in C for
how this could be done.) If you want to implement the above function
echo_infinite as a state machine, you get something like::
void echo_state_machine(UART *in, UART *out)
{
static char ch;
static int state = 0;
switch (state)
{
case 0:
if (data_available(in))
{
ch = read_byte(in);
state = 1;
}
break;
case 1:
if (ready_for_sending(out))
{
write_byte(out, ch);
state = 0;
}
break;
}
}
This code looks rather different from the above code. For this simple case,
with only two states, it is probably not that difficult, but in case you have
something like ten states, it can quickly turn into Spagetti code, that is difficult to follow, could have dupplicated code,
and could have subtile bugs. In case the function implementing your task had no
switch-statements and there is but one instance of your task, one could write
the following code using some defines that are going to be explained below:
void echo_async(UART *in, UART *out)
{
START_ASYNC
while (1)
{
while (!data_available(in))
{
WAIT
}
static char ch;
ch = read_byte(in);
while (!ready_for_sending(out))
{
WAIT
}
write_byte(out, ch);
}
END_ASYNC
}
Notice that this code looks very much like the initial version. Note the use
of static before the definition of the local variable ch. The
defines one has to use, are the following:
#define START_ASYNC static int state = 0; switch (state) { case 0:
#define WAIT state = __LINE__; return; case __LINE__:
#define END_ASYNC }
These defines make use of the fact that the 'case' statements belonging to
'switch' statement may occur everywhere in the block following the 'switch'. In
a sense, the 'switch' statement acts like a kind of 'goto' that can jump
everywhere in the code belonging to it. It also makes use of the fact that the
'__LINE__' macro returns the number of the current line. Note that
they are replaced with the line number of the line where 'WAIT' is
used, not where it is defined, according to the standard rules of how the
C-preprocessor works. See the program D241005.c for an example that uses the above functions, where
the functions echo_stm and echo_async are called a hunderd
times, which is not always enough to print the string "Hello World!". The
programs accepts a number as an argument to be used for initializing the random
generator. (Find a number that makes all the functions print the whole text.)
After the above two functions are called from main, the function
echo_infinite is called, which never terminates, meaning that the
program has to be terminated for it to end.
If one does want to use a 'switch'-statement in the code, one could use a
combination of a switch statement at the start of the function and
'goto'-statements to labels matching the various places to wait. This does
recuire one to number the states explicitly, which requires some additional
work and bookkeeping, but it could help when implementing unit tests. When
using C++, one can replace the static variables with private members of the
class the method belongs to. This technique can be used to define iterators
that are implemented as co-routines that yield results whenever needed. For a
example, see the next method of the class
InlineIncludesIterator in the program kaem_parser.cpp. For a more detailed description of all the
possible ways to implement co-routines, see also: Coroutines in C.
Seed pods in magnolia
This afternoon, after we went on a walk in the neighbourhood, I spend some time
trimming some bushes in the front garden with a hedge trimmer. I also did some
work on the magnolia and spotted some red seed pods
as can be seen in the picture below.
I am thinking about when to harvest them. If I harvest them now, the seeds
might not be mature enough. It looks like the fruits have not come out yet. If
I wait too long, the seeds might be eaten by some birds and I will not be able
to harvest the seeds. In 2013, it was on November 25 that we harvested the berries. I think, I am going to keep an
eye on it for the coming week.
Magnolia seeds
Last Monday, I already harvested one of the berries from a seed pod that had
partly opened. I kept it on my laptop. I continued checking the other pods. On
Thursday morning, I closed my laptop not realizing that the berry was there.
When I opened it in the evening, I noticed that it had crushed the berry and
revealed the seed. I placed the seed in a small pot with potting soil. This
morning, I wanted to show the pods to Conny, but
when I did so, the end of the branch with the pods, broke off, probably from
the location where the flower used to start. I noticed that there already
where two cracks at in the two remaining pods. In the evening, I opened the
cracks, took out the berries, and opened them to remove the seeds. I tasted a
bit of one of the berries, but it did not taste nice. (I immediatelly wondered
wether they are poisonous, but this seems not to be the case.) I potted those
two seeds as well. I have wrapped the pots in plastic bags and placed them in
our shed.
Going into the city
When I biked on the road called Spoordijkstraat, which means railroad dike, I
noticed some plants growing up against the sheet pile that was installed in
the past year for the bike 'highway' running from Hengelo to Enschede. The
YouTube video Bouwteamproject Aanleg F35, traject: Twekkelerzoom - Centraal
station, Enschede shows an animation of the design of the bike path and the
sheet pile starting from
0:59. Below one of the pictures I took.
At 13:44:26, I bought the booklet AKI Schilderlichting 2008 written by
Joris Geurts, Kars Persoon, Kees Smits, and Elly Strik in Dutch and German,
and published by AKI-ArtEZ Enschede in 2008 from Het Goed for € 0.50.
At TETEM art space, I saw the Model Collapse exhibition by Cyanne van den Houten and Ymer Marinus, who are part of the Telemagic collective. Before I entered the immersive exhibition, I was
told that the exhibition is not about AI, as the title of it refers to concept
of model collapse,
but about how to get an AI like ChatGPT, but about how to get there. According to the description it
'depict the landscape from which generative AI emerges. Revealing its
self-consuming origins in extraction of the earth's resources and data through
relics, artifacts and stories from the past.' I was anticipating to learn some
more about how these Large Language Models are created, but when I entered the
exhibition I was a bit confused about it. There was a large screen with some
text and about ten statue like objects with lights, buttons and displays. On
was covered with a small displays that I found quite interesting.
At Fotogalerie Objectief, I saw the exhibition People Matter with
photographs by Peter van Tuil and Frans Rentlink. From Peter van Tuil there were photographs from his books
Ergens: Malaga 2023 and HUIS & HABITAT: Pieter en WillyPeter. The later is about the
reclusive artist Pieter Derksen. Ingrid Hendriksen also took pictures of him
with some text in English, which can be viewed at: (At home with Pieter Derksen: The reclusive artist. Frans Rentlink had
a series of portrets of the surrealistic painter Charles du Bois and a friend
of him called Johan.
At Concordia, it was quite busy with people visiting the Sustainable Fashion Experience Enschede. I first looked in the front room,
where the exhibition Joystick by Madison
Bycroft (on Instagram) was held. Next, I walked around the area where Kira Fröse and Marthe
Zink are working on the Doublet #6 exhibition and then I went
upstairs to have a second look at the Triangle in Square, but there was
someone making some recording, so I did not walk around. I felt like the
video's being displayed looked different. Then I heard some singing downstairs
and it turned out that the gay men's chorus Soorten & Maten were practice singing the song 'Hotel California'
(if I am not mistaken) as a warm-up for the performance they were going to
give later. I presume as part of the opening of the exhibition It gets
better by Tim Vischer, which is part of the Rainbow Days event. I left
before the opening (also not being aware when it was).
Wind direction graph
I noticed that the wind direction graph that is shown when you select
'Expertpluim' at the Weer- en klimaatpluim en Expertpluim page on the website of the Royal Netherlands Meteorological Institute, now has been improved like
I did on July 29, 2022. I noticed that they did not
use the solution (more a hack) that I used on my page. I have not figured out how they implemented it. Maybe there is
now an option in the HighChart
library for this.
C/2023 A3 (Tsuchinshan-ATLAS)
This evening, Conny and I biked to the country road
called Borweg. (This road is named after a stronghold build by an Italian named
Bernardino Cernaego who married Anna van Scheven as is mentioned on May 20,
1585.) We went there in the hope to catch a glimse of the comet
C/2023 A3 (Tsuchinshan-ATLAS). When we arrived it was too light at the
horizon. After some time, I thought to see a faint light with some line going
up to the left. I took some pictures, one of which is shown below, in which
the faint light of the comet is visible.
Mushrooms on tree stump
This morning, just before leaving for work, I took some photographs in our
backgarden of the mushrooms that appeared on the tree
stump of the chestnut tree that we cut down
two years ago. I have no idea what kind of
mushroom it is, but I guess that it is a member of the family of polyporacae.
23,000 days
Today, it is 23,000 days ago that I was born. I decided to celebrate this
special day by treat my colleagues on (small) cake. On Tuesday, January 25, 2022, I celebrated that I was 22,000 days old.
On Sunday, 18 July 2027, I will be 24,000 days old.
I am reading Chapter 30 of ESP32-S3: Technical Reference Manual to understand how Low-level SPI
works when using it in master mode, using 1-bit SPI, 4-line half-duplex mode,
and CPU-controlled single transfer (no DMA), normal bit order, writing and/or
reading at most 4 bytes (32 bits), only using DOUT and DIN and skipping CMD and
ADDRESS (because we are using 1-bit SPI and there is no need to have those).
My notes are:
- SPI_WR_BIT_ORDER and SPI_RD_BUT_ORDER set to 0 for MSB first (the default).
- SPI_Wx_REG registers for CPU-Controlled Data Transfer (30.5.5).
- SPI_USR_MOSI_HIGHPART and SPI_USR_MISO_HIGHPART set to 0 (the default).
- SPI_DMA_RX_ENA and SPI_DMA_TX_ENA set to 0 (the default).
- SPI_CLK is generated from clk_spi_mst with SPI_CLKCNT_N and SPI_CLKDIV_PRE.
- SPI_SLAVE_MODE set to 0 (the default).
- SPI_USR_CONF set to 0 (the default) for single transfer.
- SPI_USR_COMMAND set to 0 (not the default).
- SPI_USR_COMMAND_BITLEN set to 0 (the default).
- SPI_USR_ADDR and SPI_USR_DUMMY set to 0 (the default).
- SPI_USR_ADDR_BITLEN set to 0. (The default is 23, which stands for 24 bits).
(The address is taken from the SPI_USR_ADDR_VALUE register.)
- SPI_USR_DUMMY_CYCLELEN to 0. (The default is 7.)
- SPI_USR_MOSI set to 1 when writing data (for DOUT).
- SPI_USR_MISO set to 1 when reading data (for DIN).
- SPI_USR_DATA_BITLEN set to number of bits to write and/or read. (The default is 0.)
- SPI_CS_HOLD_TIME set to 1 (the default).
- SPI_CS_HOLD set to 1 (the default).
- SPI_CS_SETUP set to 1 (the default).
- Not sure to set SPI_CS_SETUP_TIME to another value than the default 0.
- All SPI_Fx_DUAL/QUAD/OCT set to 0 (the default) for 1-bit SPI.
- SPI_USR set to 1 (to trigger a SPI operation).
- SPI_UPDATE set to 1 (to synchronize SPI registers from APB clock domain
into SPI module clock domain).
Section 30.5.8.4 'Half-Duplex Communication (1/2/4/8-bit Mode)' explains how
to set the registers for the desired SPI-usage. My notes:
- The CMD state is not mentioned as being optional. But the CMD can be 0
bits long.
- SPI_DOUTDIN set to 0 (the default).
- Set the FSPICLK according to Section 30.7.
- Configure interrupts.
- Set SPI_DMA_AFIFO_RST, SPI_BUF_AFIFO_RST, and SPI_RX_AFIFO_RST to reset
these buffers.
- Set SPI_USR to start the transfer.
The file spi_struct.h gives C struct definition for accessing the
different parts of the registers. These are used in the file
spi_ll.h. The following 'functions' can be of interest:
- spi_ll_master_init.
- spi_ll_master_cal_clock to calculate the clock settings.
- spi_ll_master_set_clock_by_reg to set these clock settings.
- spi_ll_master_set_line_mode to set the 1-bit mode.
- spi_ll_set_command_bitlen to set SPI_USR_COMMAND(_BITLEN).
- spi_ll_set_addr_bitlen to set SPI_USR_ADDR(_BITLEN).
- spi_ll_enable_mosi and spi_ll_enable_miso.
- spi_ll_set_half_duplex to set SPI_DOUTDIN.
- spi_ll_master_set_clock_by_reg to select the CS to be used.
- spi_ll_apply_config to set apply the register configurations.
- spi_ll_write_buffer to set the data to the SPI_Wx_REG registers.
- spi_ll_user_start to set SPI_USR to start the transfer.
- spi_ll_get_running_cmd to check if the command is still running.
Note that the ports of the device that is being used, also need to be set.
Book
At 16:56, I bought the book On Anarchism written by Noam Chomsky in
English and published by Penguin UK in 2013,
ISBN:9780241969601, from thrift store Rataplan
for € 0.50.
My project "Verifying and
documenting live-bootstrap" is one the selected proposals eligible to
receive a grant from NLnet
Foundation in the April 2024 NGI Zero Core call, alongside 48 other
exciting new projects. I have decided not to accept this grant, because I have
lost interest in the project, having finished most of what I wanted to achieve
and gave a presentation about it on September
29. I made an attempt to also run strace for the other supported
CPU's, but failed to do so. I have created a page to present the results and give some background and history of the
project as a kind of finalization of my investigations of the past years.
19.0° Celsius
The temperature at Twenthe Airport has gone up to
19.0° Celsius, which breaks the previous record of 18.9° on this date
in 1953.
Chasing The Dot
Conny and I went to Rijksmuseum Twenthe to see the exhibition
Chasing The Dot with installations by Philip Vermeulen. We saw the following installations:
The Chasing The Dot installation reminded me on The Brain Machine by Mitch Altman. It has a lot of flashing lights at
various frequencies. Sometimes you start to see a dot. I think this is related
to the fact that at the center of your retina there is a different
concentration of rods and cones than in the other parts of the retina.
We also watched a short documentary about Philip Vermeulen and there also was
a room with books and some (related) works. The works are:
- Untitled, Jacob Bill, 1967.
- Trames (2×), François Morellet, 1965.
- Reliëf R 74-14, Jan Schoonhoven, 1974.
- Vega-Tuz, Victor Vasarely, 1981.
- Homage to the square, Josef Albers, 1972.
Some of the books:
Conny also took a picture of me
when I was standing under a light in one of the dark rooms.
Next we saw the exhibition Gogbot x RMT (also called: The Tec Divide), which I already saw on
Friday, September 13. We watched the works in
the following order:
- You are Light an Cabbage, Diana Gheorghiu, 2023.
- Calculating Empires: A Genealogogy of Technology and Power,
1500 - 2025, Kate Crawford
& Vladan Joler. (Very large
and detailed inforgraphic.)
- Retraining Laziness, T(n)C /
Tina Kult and Agnes Varnai, in collaboration with Madeline Hall, 2023.
- Forest filled with pines and electronics, Troika, 2022.
- All Watched over by Machines of Loving Grace,
Richard Brautigan, 1967.
- Irma Watched over by Machines, Troika, 2019.
- A Boring Dystopia, Matthias Planitzer, 2023.
- 564 Tracs (
Not a love song is usually a love song),
Miloš
Trakilovió, 2023.
- The Materiality of a Natural Disaster, Hilda Hellström, 2012.
- Technosamanic Systems: New Cosmological Models for Survival,
Suzanne Treister, 2020 - Now.
- A Bestiary of the
Anthropocene, Disnovation.org, 2021.
We also walked through the exhibition PLANETART ARCHIVES X Kees de Groot 1978-2003. At one of the tables, there
was a booklet about Reset: Manifestatie over
simulatie, animatie en games in 1998 that was organized by TARt. Maybe it
was seen as a reset of the earlier TARt festivals, but it was a little
different. Kees de Groot was one of the artist at this manifestation and the
primary location was called 'Planet Art'. I never new about this 'connection'
between the TARt festivals and GOGBOT. That manifestation did include games
developed by students. Several GOGBOT festivals have included project by
students as well.
ESP32 I²C without interupts
In some bare metal embedded solutions you do not want to make use of interupts,
because they potentially could introduce unpredictable behaviour. If you want
to do this for the ESP32 it usually means that
you cannot the high-level parts of the ESP-IDF because they are based on FreeRTOS that uses interupts. The implementation of the I²C driver
makes use of interupts. The interupt handler is the function
i2c_master_isr_handler_default in the file i2c_master.c. In this function i2c_ll_get_intr_mask is
used to get the information about the interupt being raised and the function
i2c_ll_clear_intr_mask is called to clear the bits. Before, in the
function s_i2c_transaction_start, the function
i2c_ll_enable_intr_mask is called with
I2C_LL_MASTER_EVENT_INTR, which enables the interupts for:
- The ACK value received by the master is not as expected
(I2C_NACK_INT_ENA_M).
- The SCL stays high or low for more than
2I2C_T IM E_OUT_VALUE (default 16) clock cycles during
data transfer (I2C_TIME_OUT_INT_ENA_M).
- The detection of a STOP bit, signaling that the transaction is complete
(I2C_TRANS_COMPLETE_INT_ENA_M).
- The SDA's output value does not match its input value while the master's
SCL is high (I2C_ARBITRATION_LOST_INT_ENA_M), meaning that some
other device is generating signals on the bus or there is an electrical
interferance.
- The op_code of the master indicates an END command and a END condition is
detected (I2C_END_DETECT_INT_ENA_M).
The I²C driver is a bit of an overkill for the most common use of the
interface to communicate with slave periphials connected to the I²C bus,
which usually consist of transfering packets of data not larger than FIFO
send and receive buffers, which, according to the i2c_struct.h files,
are 128 bytes in size. The I²C allows for eight commands to be processed
in one run, which is enough for a combination of a write and read interaction,
where you select a register in a periphial and read out its data. Each of the
commands has a done flag (command_done field of the
i2c_comd_reg_t). This can be used to see if an I²C sequence of
commands has been completed by looking at the flag of the last command
(usually a STOP or END command). But if some reason the execution of the
sequence fails and this flag is not set, there is no way to know this, except
than to conclude after a certain time-out periode that an error has occured.
So, it seems at least if you do not want to resort to interupts. Although I do
read otherwise on various forums on the internet, I wonder if it is possible to
enable interupts and not install an interupt handler. Chapter 9 explains how
the ESP32 has an interrupt matrix to allocate peripheral interupt sources to
the two cores to be processed. In the function i2c_new_master_bus the
interupt handler i2c_master_isr_handler_default is installed by
calling the function esp_intr_alloc_intrstatus. The function is also
given the address of the interupt status register and the constents of the
irq field of the i2c_periph_signal for the specified I²C
device. This value is defined in the i2c_periph.c file and is taken
from the periph_interrput_t enumeration of periphial signals. The
function esp_intr_alloc_intrstatus (defined in the file
intr_alloc.c) tries to allocate one of the 32 interupt for periphials
(at the designated core), and after having done some more initializations and
bookkeeping calls the function esp_rom_route_intr_matrix to link the
periphial to the interupt. If you do enable interupts for a certain periphial
the contents of the matching INTERRUPT_COREx_SOURCE_y_MAP is
used. For the ESP32-S3 the valid values for these registers are 0~5, 8~10,
12~14, 17~28, 30~31, which are all the values of the category 'Periphial' in
table 9.2. However, the default value (on Reset) is 16, which is the number of
the 'Internal' category 'Timer.2' interupt. Because a periphial interupt can be
assigned to a particular core, it is logical that the value in the matrix of
the other core is not changed. So, it seems that the value 16 is the value (or
a value) to indicate that the periphial interupt is not processed for the given
core.
Book
At 17:25, I received the book jurrian van den berg: verzamelaar van
dingen written and illustrated by Linda Rusconi in Dutch and published by Lecturis in November 2024,
ISBN:9789462265271, from the Lecturis webshop for € 40.00.
This months interesting links
Home
| September 2024
| November 2024