diff --git a/app/Makefile b/app/Makefile deleted file mode 100644 index 9af4b3e67..000000000 --- a/app/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -app_objs += $(addprefix app/,\ - escher_demo.o\ - plot.o\ - utils.o) -products += $(app_objs) app.elf app.hex app.bin - -app.elf: $(app_objs) diff --git a/app/app.cpp b/app/app.cpp deleted file mode 100644 index 1cc599cc8..000000000 --- a/app/app.cpp +++ /dev/null @@ -1,179 +0,0 @@ -extern "C" { -#include -#include -#include -#include -} - -#include -#include "../poincare/src/layout/string_layout.h" - -#include "plot.h" -#include "utils.h" - -static const char* kParsingErrorMessage = "PARSING ERROR"; - -////////////////////////////////////////////////////// - -static constexpr uint8_t kInputMemory = 15; - -typedef struct user_expression_t { - char* text_input; - Expression* expression; - Expression* simplified; - ExpressionLayout* expression_layout; - ExpressionLayout* simplified_layout; -} user_expression_t; - -class UserExpressions { - public: - UserExpressions() { - m_numberOfExpressions = 0; - m_position = kInputMemory; - for (int i=0; icreateLayout(); - user_expression.simplified = user_expression.expression->simplify(); - user_expression.simplified_layout = user_expression.simplified->createLayout(); - } else { - user_expression.expression_layout = - new StringLayout(kParsingErrorMessage, strlen(kParsingErrorMessage)); - } - return user_expression; -} - -static int16_t print_user_input(user_expression_t user_expression, int16_t yOffset) { - if (user_expression.expression_layout) { - int16_t height = user_expression.expression_layout->size().height; - if (yOffset + height < ION_SCREEN_HEIGHT) { - user_expression.expression_layout->draw(KDPointMake(0, yOffset)); - } - yOffset += height; - } - if (user_expression.simplified_layout) { - int16_t height = user_expression.simplified_layout->size().height; - if (yOffset + height < ION_SCREEN_HEIGHT) { - int16_t xOffset = ION_SCREEN_WIDTH - user_expression.simplified_layout->size().width; - user_expression.simplified_layout->draw(KDPointMake(xOffset, yOffset)); - } - yOffset += height; - } - return yOffset; -} - -static void print_user_inputs(const UserExpressions& user_inputs, uint8_t startingAt) { - int16_t yOffset = 0; - for (uint8_t i=startingAt; iION_SCREEN_HEIGHT) { - break; - } - } -} - -static void interactive_expression_parsing() { - UserExpressions user_inputs = UserExpressions(); - int index = 0; - while (1) { - text_event_t text_event; - if (index == 0) { - text_event = get_text(nullptr); - } else { - text_event = get_text(user_inputs.get_expression(index - 1).text_input); - } - if (text_event.event == EQUAL) { - user_inputs.append_expression(create_user_input(text_event.text)); - } else if (text_event.event == UP_ARROW) { - index--; - if (index < 0) { - index = 0; - } - } else if (text_event.event == DOWN_ARROW) { - if (user_inputs.numberOfExpressions() != 0) { - index++; - if (index >= user_inputs.numberOfExpressions()) { - index = user_inputs.numberOfExpressions() - 1; - } - } - } else if (text_event.event == PLOT) { - user_inputs.append_expression(create_user_input(text_event.text)); - // We check that the expression is correct. - if (user_inputs.get_expression(0).expression) { - clear_screen(); - plot(user_inputs.get_expression(0).expression, -3, 3); - } - } else { - assert(false); // unreachable. - } - clear_screen(); - print_user_inputs(user_inputs, index ? index - 1 : 0); - } -} - -void ion_app() { - interactive_expression_parsing(); - while (1) { - ion_sleep(); - } -} diff --git a/app/blinky.c b/app/blinky.c deleted file mode 100644 index 379bd52a7..000000000 --- a/app/blinky.c +++ /dev/null @@ -1,44 +0,0 @@ -#include - -void sleep(long delay); - -int main(int argc, char * argv[]) { - - // We want to blink LEDs connected to GPIO pin G13 and G14 - // (this is documented in our board's PDF) - // - // GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus - // (this is documented in the STM32F4 reference mnual, page 65) - - // Step 1 : Enable clock in RCC_AHBxENR - RCC_AHB1ENR->GPIOGEN = 1; - - - // Step 2 : Configure the GPIO pin to "general purpose output - GPIO_MODER(GPIOG)->MODER13 = GPIO_MODE_OUTPUT; - GPIO_MODER(GPIOG)->MODER14 = GPIO_MODE_OUTPUT; - - // Per doc, the output is push-pull by default (yay) - // And we should also set the output speed, but really - // we don't care (we're doing something super slow) - - long delay = 50000; - - while (1) { - GPIO_ODR(GPIOG)->ODR13 = 0; - GPIO_ODR(GPIOG)->ODR14 = 1; - - sleep(delay); - - GPIO_ODR(GPIOG)->ODR13 = 1; - GPIO_ODR(GPIOG)->ODR14 = 0; - - sleep(delay); - } -} - -void sleep(long delay) { - for (long i=0; i -#include -#include -#include -#include - -void BlinkGreenLed(void * pvParameters) { - while(1) { - vTaskDelay(1000/portTICK_PERIOD_MS); - GPIO_ODR(GPIOG)->ODR13 = 0; - vTaskDelay(1000/portTICK_PERIOD_MS); - GPIO_ODR(GPIOG)->ODR13 = 1; - } -} - -void BlinkRedLed(void * pvParameters) { - int delay = 10; - while (1) { - vTaskDelay(delay); - GPIO_ODR(GPIOG)->ODR14 = 1; - vTaskDelay(delay); - GPIO_ODR(GPIOG)->ODR14 = 0; - delay++; - } -} - -int main(int argc, char * argv[]) { - // We want to blink LEDs connected to GPIO pin G13 and G14 - // (this is documented in our board's PDF) - // - // GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus - // (this is documented in the STM32F4 reference mnual, page 65) - - // Step 1 : Enable clock in RCC_AHBxENR - RCC_AHB1ENR->GPIOGEN = 1; - - - // Step 2 : Configure the GPIO pin to "general purpose output - GPIO_MODER(GPIOG)->MODER13 = GPIO_MODE_OUTPUT; - GPIO_MODER(GPIOG)->MODER14 = GPIO_MODE_OUTPUT; - - - BaseType_t success = xTaskCreate(BlinkGreenLed, - "BlkGrn", - 100, // Stack size - NULL, // Parameters - 2, - NULL); - - xTaskCreate(BlinkRedLed, "BlkRed", 100, NULL, 2, NULL); - - vTaskStartScheduler(); - - while (1) { - // We should never get here - } -} diff --git a/app/plot.cpp b/app/plot.cpp deleted file mode 100644 index bef6bbce0..000000000 --- a/app/plot.cpp +++ /dev/null @@ -1,85 +0,0 @@ -extern "C" { -#include -#include -#include -#include -} - -#include - -#include "utils.h" -#include "plot.h" - -constexpr KDCoordinate kScreenWidth = ION_SCREEN_WIDTH; -const KDCoordinate kScreenHeight = ION_SCREEN_HEIGHT; - -static float plotValues[kScreenWidth]; -static float yMin, yMax; - -// For now we only plot the axes at the origin. -// TODO: print axes not at the origin with some values too. -// TODO: label the axes. -// TODO: put the values on the axes. -static void plot_axes(float xMin, float xMax, float yMin, float yMax) { - if (xMin < 0 && xMax > 0) { - float total = xMax - xMin; - float ratio = xMax / total; - KDCoordinate width = ratio * kScreenWidth; - KDDrawLine(KDPointMake(width, 0), KDPointMake(width, kScreenHeight-1), 0xff); - } - if (yMin < 0 && yMax > 0) { - float total = yMax - yMin; - float ratio = yMax / total; - KDCoordinate height = ratio * kScreenHeight; - KDDrawLine(KDPointMake(0, height), KDPointMake(kScreenWidth-1, height), 0xff); - } -} - -static void fill_values(Expression * e, float xMin, float xMax) { - assert(e); - Context plotContext; - - // Initialize min and max. - Float xExp = Float(xMin); - plotContext.setExpressionForSymbolName(&xExp, "x"); - plotValues[0] = e->approximate(plotContext); - yMin = plotValues[0]; - yMax = plotValues[0]; - - for (KDCoordinate i = 1; i < kScreenWidth; i++) { - float x = xMin + (xMax-xMin)/kScreenWidth*i; - Float xExp = Float(x); - plotContext.setExpressionForSymbolName(&xExp, "x"); - plotValues[i] = e->approximate(plotContext); - if (plotValues[i] > yMax) { - yMax = plotValues[i]; - } - if (plotValues[i] < yMin) { - yMin = plotValues[i]; - } - } -} - -// TODO: Add a cursor. -// TODO: print the expression. -void plot(Expression * e, float xMin, float xMax) { - assert(e); - - fill_values(e, xMin, xMax); - - // Plot the original axes. - plot_axes(xMin, xMax, yMin, yMax); - - // We need to initialize the first point. - KDCoordinate j = ((plotValues[0]-yMin) / (yMax-yMin) * (kScreenHeight - 1)); - KDPoint previousPoint = KDPointMake(0, kScreenHeight - 1 - j); - - for (KDCoordinate i = 1; i < kScreenWidth; i++) { - // TODO: check for yMin == yMax - KDCoordinate j = ((plotValues[i]-yMin) / (yMax-yMin) * (kScreenHeight - 1)); - KDPoint currentPoint = KDPointMake(i, kScreenHeight - 1 - j); - KDDrawLine(previousPoint, currentPoint, 0xFF); - previousPoint = currentPoint; - } - ion_get_event(); // We wait for a text input. -} diff --git a/app/plot.h b/app/plot.h deleted file mode 100644 index e66f97bdd..000000000 --- a/app/plot.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef APP_PLOT_H -#define APP_PLOT_H - -// Note that currently the only variable is 'x' -void plot(Expression * e, float xMin, float xMax); - -#endif diff --git a/app/spi.c b/app/spi.c deleted file mode 100644 index db8aa735d..000000000 --- a/app/spi.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include - -/* This code sends data over SPI - * We're using SPI4, in this pinout - * - * PE11 - SPI4_NSS - Yellow - * PE12 - SPI4_SCK - Green - * PE13 - SPI4_MISO - Red - * PE14 - SPI4_MOSI - Blue - */ - -void SpiSend(void * pvParameters) { - uint16_t value = 0; - while(1) { - SPI_SR_t * spi_status = SPI_SR(SPI4); - if (spi_status->BSY == 0) { - uint16_t * SPI4_DR = (uint16_t *)(0x4001340C); - *SPI4_DR = value++; - } - vTaskDelay(100/portTICK_PERIOD_MS); - } -} - -int main(int argc, char * argv[]) { - // We'll use GPIO pins E11-E14 to emit SPI data - // GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus (as all GPIOs BTW) - // (this is documented in the STM32F4 reference mnual, page 65) - - // Step 1 : Enable clock in RCC_AHBxENR - RCC_AHB1ENR->GPIOEEN = 1; - - // Step 2 : Configure the GPIO pin to "Alternate function number 5" - // This means "SPI4 on pins E11-14", cf STM32F249 p78 - GPIO_MODER(GPIOE)->MODER11 = GPIO_MODE_ALTERNATE_FUNCTION; - GPIO_MODER(GPIOE)->MODER12 = GPIO_MODE_ALTERNATE_FUNCTION; - GPIO_MODER(GPIOE)->MODER13 = GPIO_MODE_ALTERNATE_FUNCTION; - GPIO_MODER(GPIOE)->MODER14 = GPIO_MODE_ALTERNATE_FUNCTION; - - // We're interested in pins 11-14, which are in the 8-16 range, so we - // have to deal with the "high" version of the AF register - GPIO_AFRH(GPIOE)->AFRH11 = GPIO_AF_AF5; - GPIO_AFRH(GPIOE)->AFRH12 = GPIO_AF_AF5; - GPIO_AFRH(GPIOE)->AFRH13 = GPIO_AF_AF5; - GPIO_AFRH(GPIOE)->AFRH14 = GPIO_AF_AF5; - - // Enable the SPI4 clock - RCC_APB2ENR->SPI4EN = 1; - - // Configure the SPI port - // Using a C99 compound litteral - *SPI_CR1(SPI4) = (SPI_CR1_t){ - .BIDIMODE = 1, - .BIDIOE = 1, - .MSTR = 1, - .DFF = SPI_DFF_16_BITS, - .CPOL = 0, - .BR = SPI_BR_DIV_256, - .SSM = 1, - .SSI = 1, - .SPE = 1 - }; - - BaseType_t success = xTaskCreate(SpiSend, - "SpiSnd", - 100, // Stack size - NULL, // Parameters - 2, - NULL); - - vTaskStartScheduler(); - - while (1) { - // We should never get here - } -} diff --git a/app/utils.cpp b/app/utils.cpp deleted file mode 100644 index db8ab9df2..000000000 --- a/app/utils.cpp +++ /dev/null @@ -1,195 +0,0 @@ -extern "C" { -#include -#include -#include -#include -} - -#include "utils.h" - -static constexpr int16_t kPromptHeight = 25; -static constexpr uint8_t kBufferSize = 255; - -void clear_screen() { - KDRect r; - r.x = 0; - r.y = 0; - r.width = ION_SCREEN_WIDTH; - r.height = ION_SCREEN_HEIGHT; - KDFillRect(r, 0x00); -} - -static void clear_prompt() { - KDRect r; - r.x = 0; - r.y = ION_SCREEN_HEIGHT - kPromptHeight; - r.width = ION_SCREEN_WIDTH; - r.height = kPromptHeight; - KDFillRect(r, 0x00); -} - -static void print_prompt(char* text, int index) { - char* tmp = (char*) " "; - KDSize font_size = KDStringSize(tmp); - KDDrawLine(KDPointMake(0, ION_SCREEN_HEIGHT - kPromptHeight), - KDPointMake(ION_SCREEN_WIDTH, ION_SCREEN_HEIGHT - kPromptHeight), 0xff); - KDDrawString(text, KDPointMake(0, ION_SCREEN_HEIGHT - (kPromptHeight / 2)), 0); - KDDrawChar(text[index], KDPointMake(index * font_size.width, ION_SCREEN_HEIGHT - (kPromptHeight / 2)), true); -} - -static void clear_trig_menu() { - { - KDRect r; - r.x = ION_SCREEN_WIDTH / 4 - 1; - r.y = ION_SCREEN_HEIGHT / 4 - 1; - r.width = ION_SCREEN_WIDTH / 2 + 2; - r.height = ION_SCREEN_HEIGHT / 2 + 2; - KDFillRect(r, 0x00); - } -} - -static void print_trig_menu() { - { - KDRect r; - r.x = ION_SCREEN_WIDTH / 4; - r.y = ION_SCREEN_HEIGHT / 4; - r.width = ION_SCREEN_WIDTH / 2; - r.height = ION_SCREEN_HEIGHT / 2; - KDDrawRect(r, 0xff); - } -} - -static int get_trig_input(char* input) { - int pos = 0; - const char* kTexts[] = { - "sine", - "cosine", - "tangent", - "cancel" - }; - const char* kOutputs[] = { - "sin( )", - "cos( )", - "tan( )", - }; - const KDPoint orig = KDPointMake(ION_SCREEN_WIDTH / 4, ION_SCREEN_HEIGHT / 4); - while (true) { - print_trig_menu(); - - uint16_t vert_acc = 0; - for (int i(0); i<4; i++) { - KDSize text_size = KDStringSize(kTexts[i]); - KDDrawString(kTexts[i], - KDPointMake(orig.x, orig.y + vert_acc + text_size.height / 2), - i==pos); - vert_acc += text_size.height; - } - - ion_event_t event = ion_get_event(); - if (event == UP_ARROW) { - pos--; - if (pos < 0) { - pos = 0; - } - } else if (event == DOWN_ARROW) { - pos++; - if (pos >= 4) { - pos = 3; - } - } else if (event == '=') { - clear_trig_menu(); - if (pos == 3) { - return 0; - } else { - memcpy(input, kOutputs[pos], (size_t) strlen(kOutputs[pos])); - return strlen(kOutputs[pos]); - } - } - } -} - -text_event_t get_text(char* txt) { - char input[kBufferSize]; - int index = 0; - int max = 0; - text_event_t text_event = {nullptr, ERROR}; - - for (int i = 0; i < kBufferSize; i++) { - input[i] = 0; - } - - if (txt != nullptr) { - index = strlen(txt); - max = index; - memcpy(input, txt, (size_t) index); - } - - input[max] = ' '; - input[max+1] = '\0'; - - while (1) { - clear_prompt(); - print_prompt(input, index); - ion_event_t event = ion_get_event(); - if (event == EQUAL) { - input[max] = '\0'; - text_event.event = EQUAL; - text_event.text = (char*) malloc(sizeof(char) * (index + 1)); - memcpy(text_event.text, input, (size_t) (index + 1)); - break; - } else if (event == LEFT_ARROW) { - index--; - if (index < 0) { - index = 0; - } - } else if (event == RIGHT_ARROW) { - if (index < max) { - index++; - } - } else if (event <= 0x7f) { - input[index++] = (char) event; - // We are at the end of the line. - if (index > max) { - max=index; - input[max] = ' '; - input[max+1] = '\0'; - } - } else if (event == TRIG_MENU) { - int tmp = get_trig_input(&input[index]); - index+=tmp; - if (index > max) { - max=index; - input[max] = ' '; - input[max+1] = '\0'; - } - // we want to be inside the parenthese if there are some. - index -= (tmp > 2) ? 2 : 0; - } else if (event == DELETE) { - // Nothing to delete. - if (index == max) { - continue; - } - for (int i=index; i -} - -typedef struct { - char* text; - ion_event_t event; -} text_event_t; - -/* Returns a pointer to an input text allocated by the functions. - * Also returns an event, which is its return reason. - * - * This function can get a text to work on instead of starting from an empty - * string. */ -text_event_t get_text(char* txt); - -void clear_screen(); - -#endif // APP_UTILS_H