Add more comments

This commit is contained in:
schmelczerandras 2020-04-19 20:55:44 +02:00
commit b5a95218ea
25 changed files with 200 additions and 60 deletions

View file

@ -22,7 +22,7 @@
<ProgFlashFromRam>true</ProgFlashFromRam>
<RamSnippetAddress>0x20000000</RamSnippetAddress>
<UncachedRange />
<preserveEEPROM>true</preserveEEPROM>
<preserveEEPROM>false</preserveEEPROM>
<OverrideVtorValue>exception_table</OverrideVtorValue>
<BootSegment>2</BootSegment>
<ResetRule>0</ResetRule>

View file

@ -43,6 +43,7 @@ void turnDisplayOnOff(bool shouldBeOn) {
sendByteOnSPI(0x8D | shouldBeOn); // set charge pump on/off
sendByteOnSPI(0x10 | shouldBeOn << 2); // set charge pump on/off
sendByteOnSPI(0xAE | shouldBeOn); // turn display sleep on/off
dataMode();
}
void initializeDisplay(DrawFunction drawEverything) {

View file

@ -7,30 +7,65 @@
#include "../../util/rectangle/rectangle.h"
/*
SPI driver for D096-12864
*/
#define DISPLAY_RESET_OUTPUT_PIN PB0
#define DISPLAY_DC_OUTPUT_PIN PB4
// A two-times downscaling is used for greater performance
#define DISPLAY_WIDTH_IN_PIXELS 64
#define DISPLAY_HEIGHT_IN_PIXELS 32
// To easily access the window size
#define WINDOW ((Rectangle){(Vec2){0, 0}, (Vec2){DISPLAY_WIDTH_IN_PIXELS, DISPLAY_HEIGHT_IN_PIXELS}})
// To conserve RAM, drawing is done in chunks of DEFAULT_COMPOSITING_WINDOW size
// instead of buffering the whole display and writing it out at once
#define DEFAULT_COMPOSITING_WINDOW ((Rectangle){(Vec2){0, 0}, (Vec2){DISPLAY_WIDTH_IN_PIXELS, 8}})
typedef void (*DrawFunction)(Rectangle);
// Call DrawFunction n times after a call to drawFrame has been made
void initializeDisplay(DrawFunction drawEverything);
// Set a the brightness of the display
// Value can be any number between 0 and 255.
void setDisplayContrast(uint8_t value);
void turnDisplayOnOff(bool shouldBeOn);
// To conserve program memory, pixel based intersection test
// is implemented here.
// Calling draw functions after calling startIntersectionTest
// will set a wasIntersection bit appropriately.
// Clear buffer and wasIntersection bit
void startIntersectionTest();
// Return wasIntersection bit
bool endIntersectionTest();
// Initiate a draw sequence
void drawFrame();
void drawBitmapFromProgMem(Rectangle boundingBox, uint16_t const data[boundingBox.size.x][(boundingBox.size.y + 7) / 8], bool isMirrored);
// for white rectangle: invertedMask: don't care, fill: 0xFF
// for black rectangle: invertedMask: 0xFF, fill: 0x00
// Draw a sprite of size boundingBox.size at boundingBox.position from bitmap
// if isMirrored then mirror around the vertical axis
// Bitmap's data is interpreted the following way:
/*
Each 16 bit word corresponds to an 8 pixel high column.
(These columns are laid out horizontally from left to right. Unfortunately,
the display uses this addressing mode.) The higher 8 bits of the word is the
an inverted mask and the lower 8 bits are the fill bits.
newPixelColumn = oldPixelColumn & ~invertedMask | fill;
This seemingly weird layout is used to take advantage of SIMD operations
and speed up the drawing process significantly.
*/
void drawBitmapFromProgMem(Rectangle boundingBox, uint16_t const bitmap[boundingBox.size.x][(boundingBox.size.y + 7) / 8], bool isMirrored);
// Draw a one byte repeated texture covering the parameter box
// for a white rectangle use these arguments: invertedMask: don't care, fill: 0xFF
// for a black rectangle use these arguments: invertedMask: 0xFF, fill: 0x00
void drawFilledRectangle(Rectangle box, uint8_t invertedMask, uint8_t fill);
#endif

View file

@ -5,13 +5,19 @@
#include <avr/io.h>
/*
Custom NEC implementation using a TSOP4838
*/
#define INFRA_ADDRESS 255
#define IR_PIN PB3
#define IR_PIN PB4
#define REPEAT_CODE 1
typedef void (*OnCommandReceived)(uint8_t);
typedef void (*OnReceiveStarted)();
void initializeInfra(OnCommandReceived onCommandReceived, OnReceiveStarted onReceiveStarted);
// Initialize infra and call onCommandReceived with every received byte
// Call onCommandReceived with the argument REPEAT_CODE if a repeat code
// has been received.
void initializeInfra(OnCommandReceived onCommandReceived);
#endif

View file

@ -4,12 +4,10 @@
#include <stdbool.h>
#include <avr/io.h>
// FrameFunction gets previousFrameTime (in milliseconds) as argument
typedef bool (*FrameFunction)(uint8_t);
// frameFunction gets previousFrameTime (in milliseconds) as argument
// Call function every frameLengthInMilliseconds while it returns true
void startFrameLoop(FrameFunction function, uint8_t frameLengthInMilliseconds);
void powerOff();
#endif

View file

@ -12,22 +12,49 @@
#include "output_pins/output_pins.h"
/*
This module contains the lowest level functions to manipulate the hardware.
You only have to include this header file which serves as a facade.
The sub-modules' implementation can be freely changed as long as they
still implement these functions.
*/
// Initialize every hardware element at once
void initializeHardwareAccess();
// writing of unchanged byte is atomic
// Write a single byte, when finished call the callback method
// Writing of unchanged byte is atomic.
bool asyncWriteEEPROM(uint8_t* buffer, OnEEPROMFinished onFinished);
uint8_t loadSavedByteEEPROM(uint8_t address);
// Load byte from pointer
uint8_t loadByteEEPROM(uint8_t* address);
// Load 2 bytes from pointer
uint16_t loadWordEEPROM(uint16_t const* address);
// Load byte from address
// It is different from loadByteEEPROM because
// accepts a relative address instead of an
// absolute one.
uint8_t loadSavedByteEEPROM(uint8_t address);
// Enable the asynchronous writing of data from buffer
void enableWritingEEPROM();
void disableWritingEEPROM();
// Enable interrupt OCCRA for TIMER0 with a modulo of triggerInterruptInXTicks
void enableTimerA(uint8_t triggerInterruptInXTicks);
// Enable interrupt OCCRB for TIMER0B with a modulo of triggerInterruptInXTicks
void enableTimerB(uint8_t triggerInterruptInXTicks);
void disableTimerB();
// Send a single byte on the built-in SPI interface
// The transfer is done in a serial manner to achieve
// greater throughput.
void sendByteOnSPI(uint8_t byte);
// Set the value of an output pin
void setOutputPin(uint8_t id, bool value);
#endif
#endif

View file

@ -7,7 +7,7 @@
inline void initializePowerSaving() {
setBit(ACSR, ACD); // disable ADC to save power
PRR = BV(PRTIM1) | BV(PRADC); // disable power of timer1 and ADC
PRR = BV(PRTIM1) | BV(PRADC); // disable power to timer1 and ADC
}
#endif

View file

@ -12,6 +12,4 @@ inline void initializeSPI() {
DDRB |= BV(DO_PIN) | BV(USCK_PIN); // set pin directions for MOSI and SCK
}
void sendByteOnSPI(uint8_t byte);
#endif

View file

@ -4,9 +4,20 @@
#include <avr/io.h>
// Setup the drivers, and business layer objects and their relations
// It is kind of a very basic dependency injection.
void setupConnections();
// Start drawing frames and ticking objects
void startGame();
// Make the machine go to sleep
void handleOff();
// Increase or decrease the contrast (brightness) of the display
// by the given value
// The contrast can be any number between 0 and 255.
// The function automatically clamps the contrast.
void changeDisplayContrast(int8_t by);
#endif

View file

@ -46,7 +46,7 @@ bool generateAstronautPredicate(Rectangle* proposedBoundingBox) {
return (
(
(getCountOf(&Astronaut) == 1 && spaceshipObject->as.spaceship.progress >= hasHalfCrew) ||
(getCountOf(&Astronaut) == 2 && spaceshipObject->as.spaceship.progress >= hasFullCrew)
(getCountOf(&Astronaut) == 2 && spaceshipObject->as.spaceship.progress >= hasTable)
) &&
getIntersectingObjectOfType(*proposedBoundingBox, &Astronaut) == NULL &&
isOnboard(*proposedBoundingBox)

View file

@ -46,8 +46,7 @@ typedef enum {
hasBeds = 2,
hasTurret = 5,
hasHalfCrew = 8,
hasFullCrew = 15,
hasTable = 25,
hasTable = 15
} Progress;
struct _spaceship_t {