Display something (with SPI library)
V0.1 is just to do the bare minimum in C to just light a few dots on the display. That was easy and took only "a few minutes".
/*
PONG in C
V0.1 - just display something
*/
#include <SPI.h> // H/W uses pin 13, 12, 11, pin 11 is MOSI output
void setup() {
SPI.begin ();
pinMode(10,OUTPUT);
//SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE3)); // MOSI normally low.
}
void loop() {
digitalWrite(10,LOW);
SPI.transfer(0x05);
SPI.transfer(0xAA);
digitalWrite(10,HIGH);
delay(5555) ;
digitalWrite(10,LOW);
SPI.transfer(0x03);
SPI.transfer(~0xAA);
digitalWrite(10,HIGH);
delay(5555) ;
}
Yes, all hardcoded values.
Display something (with port access)
The second pre-test version was to avoid using the SPI library.
This required peeking in the SPI library and (sorry) cut-n-paste the initialisation code. I tried to match this with the AVR manual description of the bits in the SPI control register. If the AVR manual was the only information source I probably would not have managed, possibly simply brute force trying all combinations until it worked.
The same with the send-one-byte routine.
This only took "half an hour".
// (Cant find where they are defined, so doing it myself
// SPI pins are hardwired to 13, 12 & 11
#define PORT_SPI PORTB // The SPI port is part of Port B
#define DDR_SPI DDRB // -"-"
#define DD_MISO DDB4 // Port number for pin 11
#define DD_MOSI DDB3 // (not using this - pin 12)
#define DD_SCK DDB5 // Port number for pin 13
byte CSS = 10 ; // the ChipSelect pin
void SPIout ( byte Bits ) {
// Output a byte to SPI - block until complete
SPDR = Bits ;
while(!(SPSR & (1<<SPIF)) ) ; // Wait until complete
}
void setup() {
// to be nicer it should mask the other pins, ie not change them
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK); // Set MOSI and SCK output, all others input
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); // Enable SPI, Controller, set clock rate fck/16
pinMode(10,OUTPUT); // Ready the chip select
}
void loop() {
digitalWrite(10,LOW);
SPIout(0x05);
SPIout(0xAA);
digitalWrite(10,HIGH);
delay(5555) ;
digitalWrite(10,LOW);
SPIout(0x03);
SPIout(~0xAA);
digitalWrite(10,HIGH);
delay(5555) ;
}
Bouncing ball
The last extension of this test C suite was to have a single dot bounce around.
.. same #defines as previous version...
byte CSS = 10 ; // the ChipSelect pin
// Variables
byte BallXcurr, BallYcurr ; // last, current position [0,15/1,8]
byte BallXdir, BallYdir ; // just +/- for 45 degrees motion [0,1]
void SPIout ( byte Bits ) {
// Output a byte to SPI - block until complete
SPDR = Bits ;
while(!(SPSR & (1<<SPIF)) ) ; // Wait until complete
}
void RowSet ( byte RowNum, unsigned int RowBits ) {
// Fill a whole row (16 bits)
digitalWrite(CSS,LOW);
SPIout(RowNum) ; SPIout(RowBits&0xff) ;
SPIout(RowNum) ; SPIout(RowBits>>8) ;
digitalWrite(CSS,HIGH);
}
void setup() {
pinMode(11,OUTPUT); pinMode(13,OUTPUT) ;
// Direct manipulation: DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK); // Set MOSI and SCK output, all others input
// (to be nicer it should mask the other pins, ie not change them)
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); // Enable SPI, Controller, set clock rate fck/16
pinMode(10,OUTPUT); // Ready the chip select
BallXcurr = 5 ; BallYcurr = 5 ;
}
void loop() {
RowSet(BallYcurr,0x00) ; // extinguish current position
if ( BallXcurr==0 ) BallXdir=1 ; if ( BallXcurr==15 ) BallXdir=0 ; // bounce if needed
if ( BallXdir==1 ) BallXcurr++ ; else BallXcurr-- ; // advance
if ( BallYcurr==1 ) BallYdir=1 ; if ( BallYcurr==8 ) BallYdir=0 ; // bounce if needed
if ( BallYdir==1 ) BallYcurr++ ; else BallYcurr-- ; // advance
RowSet(BallYcurr,1<<BallXcurr) ;
delay(33);
}
I spent a little more time on this, partly with finding out the up/down, numbering starting at 0 or 1, and other minor details. (We all know the devil is in the details, right?) Sorry about the the code not being effective, pretty or educational, it is just a quick ProofOfConcept. Works in the simulator (havn't build the hardware yet)
Next ...?
Well, I do not really want to write the whole game in C. If I continue this it will be to include the button reading in a loop. Involving interrupts is also possible. So there may come a Part 2 or maybe not.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.