2 Commits

9 changed files with 78 additions and 38 deletions

View File

@ -11,7 +11,7 @@ CFLAGS=-Wall -mmcu=$(MCU) -std=gnu99 -I $(TOOLCHAIN_PREFIX)/include -O1 -g0
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
$(ARTIFACT).elf: main.o led.o scheduler.o canvas.o shapes.o game.o buttons.o myrand.o $(ARTIFACT).elf: main.o spi.o scheduler.o canvas.o shapes.o game.o buttons.o myrand.o
$(CC) -o $@ $(LDFLAGS) $^ $(CC) -o $@ $(LDFLAGS) $^
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt $(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt

View File

@ -6,8 +6,6 @@
#include "scheduler.h" #include "scheduler.h"
#include "shapes.h" #include "shapes.h"
#include "canvas.h" #include "canvas.h"
#include "led.h"
static uint8_t buttonsMoveLeftPressed() { static uint8_t buttonsMoveLeftPressed() {

View File

@ -4,6 +4,7 @@
#include <msp430g2553.h> #include <msp430g2553.h>
#include "canvas.h" #include "canvas.h"
#include "spi.h"
static uint8_t canvasStorage[CANVAS_WIDTH * CANVAS_HEIGHT]; static uint8_t canvasStorage[CANVAS_WIDTH * CANVAS_HEIGHT];
@ -20,17 +21,12 @@ const canvas_t miniCanvas = {
.canvas = miniCanvasStorage .canvas = miniCanvasStorage
}; };
inline static void spiSendOctet(uint8_t v) {
// wait for TX buffer empty
while (!(UC0IFG & UCB0TXIFG));
// load octet into TX buffer
UCB0TXBUF = v;
}
void canvasShow() { void canvasShow() {
// wait for signal waiting for data // wait for signal waiting for data
while (!(P1IN & BIT3)); while (!(P1IN & BIT3));
spiSendBegin(e_SPI_CANVAS);
for (uint8_t i = 0; i < (CANVAS_WIDTH*CANVAS_HEIGHT); i++) { for (uint8_t i = 0; i < (CANVAS_WIDTH*CANVAS_HEIGHT); i++) {
if ((*((canvas.canvas)+i) & 0x80) != 0) { if ((*((canvas.canvas)+i) & 0x80) != 0) {
*((canvas.canvas)+i) &= ~0x80; *((canvas.canvas)+i) &= ~0x80;
@ -46,35 +42,14 @@ void canvasShow() {
} }
} }
spiSendOctet(0xfe); spiSendOctet(0xfe);
spiSendEnd(e_SPI_CANVAS);
} }
void canvasInit() { void canvasInit() {
// SPI in master mode
UCB0CTL0 = UCMST;
// SPI timing config
UCB0CTL1 = UCSSEL_3;
// Faster than 8 ends up in strange communication errors
// between the both MCUs.
// With 8 the transfer of a complete 110 pixel canvas takes
// about 720us.
// 8 was still too fast and caused problems.
UCB0BR0 = 16;
UCB0BR1 = 0;
// BIT5: UCB0CLK
// BIT6: UCB0SOMI
// BIT7: UCB0SIMO
P1SEL |= BIT5 | BIT6 | BIT7;
P1SEL2 |= BIT5 | BIT6 | BIT7;
P1DIR |= BIT5 | BIT7;
// P1.3 is signal line // P1.3 is signal line
P1DIR &= ~BIT3; P1DIR &= ~BIT3;
// enable SPI module
UCB0CTL1 &= ~UCSWRST;
canvasClear(); canvasClear();
miniCanvasClear(); miniCanvasClear();
canvasShow(); canvasShow();

View File

@ -5,12 +5,12 @@
#include "time.h" #include "time.h"
#include "scheduler.h" #include "scheduler.h"
#include "led.h"
#include "canvas.h" #include "canvas.h"
#include "game.h" #include "game.h"
#include "buttons.h" #include "buttons.h"
#include "shapes.h" #include "shapes.h"
#include "myrand.h" #include "myrand.h"
#include "spi.h"
int main() { int main() {
@ -26,7 +26,7 @@ int main() {
schInit(); schInit();
ledInit(); spiInit();
myRandInit(); myRandInit();
canvasInit(); canvasInit();

50
game-ctrl/spi.c Normal file
View File

@ -0,0 +1,50 @@
#include <msp430g2553.h>
#include "spi.h"
void spiInit() {
// SPI in master mode
UCB0CTL0 = UCMST;
// SPI timing config
UCB0CTL1 = UCSSEL_3;
// Faster than 8 ends up in strange communication errors
// between the both MCUs.
// With 8 the transfer of a complete 110 pixel canvas takes
// about 720us.
// 8 was still too fast and caused problems.
UCB0BR0 = 16;
UCB0BR1 = 0;
// BIT5: UCB0CLK
// BIT6: UCB0SOMI
// BIT7: UCB0SIMO
P1SEL |= BIT5 | BIT6 | BIT7;
P1SEL2 |= BIT5 | BIT6 | BIT7;
P1DIR |= BIT5 | BIT7;
// Device Select Lines: 0: Canvas, 1: Display, 2: Sound
P1DIR |= BIT0 | BIT1 | BIT2;
// Disable all of them
P1OUT |= BIT0 | BIT1 | BIT2;
// enable SPI module
UCB0CTL1 &= ~UCSWRST;
}
void spiSendBegin(t_SpiDeviceSelector d) {
uint16_t bit = ((uint16_t[]){ BIT0, BIT1, BIT2 })[d];
P1OUT &= ~bit;
}
void spiSendEnd(t_SpiDeviceSelector d) {
while (UCB0STAT & UCBUSY);
uint16_t bit = ((uint16_t[]){ BIT0, BIT1, BIT2 })[d];
P1OUT |= bit;
}
void spiSendOctet(uint8_t v) {
// wait for TX buffer empty
while (!(UC0IFG & UCB0TXIFG));
// load octet into TX buffer
UCB0TXBUF = v;
}

16
game-ctrl/spi.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _SPI_H_
#define _SPI_H_
#include <stdint.h>
typedef enum { e_SPI_CANVAS, e_SPI_DISPLAY, e_SPI_SOUND } t_SpiDeviceSelector;
void spiInit();
void spiSendBegin(t_SpiDeviceSelector d);
void spiSendEnd(t_SpiDeviceSelector d);
void spiSendOctet(uint8_t v);
#endif // _SPI_H_

View File

@ -96,11 +96,12 @@ init:
;; BIT3: Signal waiting for data ;; BIT3: Signal waiting for data
mov.b #BIT0|BIT1|BIT2|BIT3, &P1DIR mov.b #BIT0|BIT1|BIT2|BIT3, &P1DIR
mov.b #0,&P1OUT mov.b #0,&P1OUT
;; BIT4: spi, UCB0STE
;; BIT5: spi, UCB0CLK ;; BIT5: spi, UCB0CLK
;; BIT6: spi, UCB0SOMI ;; BIT6: spi, UCB0SOMI
;; BIT7: spi, UCB0SIMO ;; BIT7: spi, UCB0SIMO
mov.b #BIT5|BIT6|BIT7, &P1SEL mov.b #BIT4|BIT5|BIT6|BIT7, &P1SEL
mov.b #BIT5|BIT6|BIT7, &P1SEL2 mov.b #BIT4|BIT5|BIT6|BIT7, &P1SEL2
;; BIT4: long pulse ;; BIT4: long pulse
;; BIT1: short pulse ;; BIT1: short pulse
mov.b #BIT1|BIT4,&P2DIR mov.b #BIT1|BIT4,&P2DIR
@ -122,7 +123,7 @@ init:
;; spi configuration ;; spi configuration
;; USCI B to slave mode ;; USCI B to slave mode
mov.b #UCSYNC, &UCB0CTL0 mov.b #UCSYNC|UCMODE_2, &UCB0CTL0
mov.b #0x00, &UCB0CTL1 mov.b #0x00, &UCB0CTL1
;; make sure the isr will not immediately start ;; make sure the isr will not immediately start