Welcome to the 2017 edition of the communication challenge. As every year, ROSE students are expected to perform a series of steps showing that they are comfortable with designing and writing code to solve basic problems.
Please ensure that you respect the rules of the challenge:
- You will be assigned an IP address to use on your STM32P407 board. You are not allowed to use this IP address on anything else than your board (e.g., your computer), or to use any other IP address on your board. Using someone else IP address would be considered cheating.
- Your code must be located in a directory named “challenge2017” at the root of your private git repository, and development must happen on the “master” branch.
- After every successful step, you must ensure that your code is clean and well organized, and you must commit and push it to GitLab. You must tag it with a “challenge-stepN” tag, where N is the step number, and you must push the tag as well.
Note: all the URL you will encounter that allow you to start a step are stable, which means that even if you have to use a token in the request (for example, if you need to use an address such as
http://antinea.enst.fr/challenge/step2?token=12345678&initials=XX, you will be able to use it again without restarting from scratch as the token will always be identical). For this reason, you might want to store them.
The goal of this step is to ensure that you are able to retrieve information from the network and transmit it onto the serial over USB link.
After getting your board IP address and network configuration from this page (internal link only), you must access the following HTTP content from your board:
XX are your initials as shown in the table.
For example, John Doe would issue, from its board, a proper request such as:
GET /challenge/step1?initials=XX HTTP/1.0 Host: antinea.enst.fr [empty line here]
This request would be sent over TCP to the address of antinea.enst.fr (126.96.36.199) on port 80.
As a rule for this challenge:
- You must always add a correct
Hostheader (for example,
- Every request must contain, in its query string, your
initialsand, after step 1, a
The answer contains an HTML page that you can transmit over your serial over USB link in order to read it. In this page, you will find the URL to use for the next step. Yes, you will have to parse HTML with your eyes. But don’t worry, this is easy and also the page is very short.
The goal of this step is to ensure that you are able to properly separate the headers and the body of the HTTP response.
A request to the link given at the previous step will return a simple text document containing only a new URL. You must query this new URL within two seconds of time, after which it will have expired. The content of this new URL is yet another URL, that will be used for the next step.
For example, the dialog might look like this:
>>> GET http://antinea.enst.fr/challenge/step2?token=12345678&initials=XX <<< http://antinea.enst.fr/challenge/step2done?timestamp=1427386805106&check=328e131e&token=12345678&initials=XX >>> GET http://antinea.enst.fr/challenge/step2done?timestamp=1427386805106&check=328e131e&token=12345678&initials=XX <<< http://antinea.enst.fr/challenge/step3?token=87654321&initials=XX
The goal of this step is to ensure that you are able to parse simple input and provide the user with some interaction.
A request to the link given at the previous step will return a simple text document containing (one item per line):
- The URL to use to submit the answer, to which you will have to add “&answers=ABCDE” where A, B, C, D, and E, are the index (starting from 1) of the correct answers to the questions (one per question).
- The first question, then the four possible answers
- The second question, then the four possible answers
- The fifth question, then the four possible answers
If your answers are right, you will be given the URL of the next step. Otherwise, you will be presented with an error message.
For example, the dialog might look like this (in this example, there are only two questions, while you will get five of them):
>>> GET http://antinea.enst.fr/challenge/step3?token=87654321&initials=XX <<< http://antinea.enst.fr/challenge/step3done?check=837461da&token=87654321&initials=XX This is the first question? No Yes Certainly not I don't think so Is this the second question? Yes No No No >>> GET http://antinea.enst.fr/challenge/step3done?check=837461da&token=87654321&initials=XX&answers=21 <<< http://antinea.enst.fr/challenge/step4?token=abcd1234&initials=XX
Note that an alternate (a bit less serious) question set might be mixed in by adding “&flavour=mixed” to the step3 request.
The goal of this step is to ensure that you are able to use a new peripheral on your board. You will be provided with external LCD 84×48 black&white screens that can be connected to your board using the expansion port. Those screens are driven through SPI and two additional control lines (reset and control/data selection).
LCD_RESETn: PG10. Set low to reset the display controller.
LCD_D/C: PG12. A0 in the controller datasheet. Set low to send a command, set high to send a data.
LCD_CSn: PF8 (shared with the RED LED). Chip select of the display controller. Set low to enable SPI access.
The LCD display controller will be used in “SPI 4 wire mode”. Check datasheet page 10 and following to set the STM32 SPI correct settings (clock polarity, …). You might want to check page 32 and following to set a suitable SPI clock frequency.
To initialize the LCD you need to perform these steps in the following order :
- wait for at least 15ms
- wait for at least 15ms
- send the command 0x21 (put LCD in command set 01, see page 17 of datasheet)
- send the command 0xF8 (set LCD contrast – you might want to tweak this value)
- send the commands 0x05 then 0x40 (set start line to 64)
- send the command 0x12 (set bias mode to 1:68)
- send the command 0x20 (put LCD in command set 00 and put LCD in normal mode. See page 17 of datasheet, “Function Set” command page 18)
- send the command 0x08 (set LCD to display off, see “Display Control” function, page 18)
- send the command 0x0C (set LCD to display on, see “Display Control” function, page 18)
The LCD is comprised of 6 lines, each line beeing 8 vertical pixels x 84 horizontal pixels. To update a line:
- Set the RAM pointer position to the beginning of the line. See commands “Set X addr of RAM” and “Set Y addr of RAM” page 17 and 20. X is comprised between 0 and 83, Y is comprised between 0 and 5.
- Send the data corresponding to the line (8 vertical pixels by 84). After each byte sent, the current pointer is automatically incremented by 1 along X axis.
Using the URL obtained from the previous step, you will be served with a 504 bytes binary content containing a full image to display on your screen. The first 84 bytes represent the content of the first line (each line is made of 8 rows of pixels, the least significant bit being on top), the next 84 bytes the content of the next line, and so on.
By sending the binary data to the LCD, you will get an extra string to add to this step URL (in the form of a “&check=XXXX” argument). Reading the content of this URL with the extra string added will give you, in plain text, the URL of the next step.
Tip : if you can’t get the LCD to work, you might want to check first that the STM32F4 SPI is sending commands / data correctly by plugging a logic analyzer on the UEXT pins. If everything is OK with the SPI, modify the contrast settings.
The goal of this step is to ensure that you are able to use yet another new peripheral on your board.
Using the URL obtained from the previous step, you can download an image to display on your LCD screen. This image represents a maze, and your position is drawn with a black square located on the left column. Your goal is to reach the end of the maze which is located on the far right side (you are looking for a hole in the wall).
To move your avatar around, you have to add a “&direction=SSS” to the URL (once you have obtained the maze) where SSS is one of “up”, “down”, “right”, and “left”. Providing another string will do nothing, providing a direction in which you cannot move will also do nothing. Every one of those requests returns an image that you can display. The last image, once you have reached the output, will give a string to add to the original URL to get to the next step URL, as was done previously.
You are expected to use the joystick present on your board to generate those move requests.
The goal of this step is to ensure that you did not forget to debounce your joystick.
It is similar to the previous step, except that any impossible move will have you start again from the beginning of the maze.