Added spi basic control.
This commit is contained in:
		
							parent
							
								
									8f67837925
								
							
						
					
					
						commit
						4dfad70e9b
					
				
							
								
								
									
										45
									
								
								build.d
								
								
								
								
							
							
						
						
									
										45
									
								
								build.d
								
								
								
								
							| 
						 | 
				
			
			@ -9,6 +9,8 @@ import std.file;
 | 
			
		|||
import std.string;
 | 
			
		||||
import std.conv;
 | 
			
		||||
import std.path;
 | 
			
		||||
import std.digest.md;
 | 
			
		||||
import std.base64;
 | 
			
		||||
 | 
			
		||||
const string MCU_ID = "atmega328p";
 | 
			
		||||
const ulong CPU_FREQ = 16_000_000;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +30,11 @@ int main(string[] args) {
 | 
			
		|||
        return build();
 | 
			
		||||
    }
 | 
			
		||||
    string command = args[1].strip.toLower;
 | 
			
		||||
    if (command == "build") return build();
 | 
			
		||||
    if (command == "flash") {
 | 
			
		||||
        build().quitIfNonZero();
 | 
			
		||||
        return flashToMCU(buildPath("bin", "gympal.hex"));
 | 
			
		||||
    }
 | 
			
		||||
    if (command == "build") return build(true);
 | 
			
		||||
    if (command == "clean") return clean();
 | 
			
		||||
 | 
			
		||||
    writefln!"Unknown command: \"%s\"."(command);
 | 
			
		||||
| 
						 | 
				
			
			@ -40,18 +46,18 @@ int clean() {
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int build() {
 | 
			
		||||
int build(bool force = false) {
 | 
			
		||||
    if (!exists(BUILD_DIR)) mkdir(BUILD_DIR);
 | 
			
		||||
    string[] sources = findFiles(SOURCE_DIR, ".c");
 | 
			
		||||
    writefln!"Found %d source files."(sources.length);
 | 
			
		||||
    string[] objects;
 | 
			
		||||
    objects.reserve(sources.length);
 | 
			
		||||
    foreach (source; sources) {
 | 
			
		||||
        objects ~= compileSourceToObject(source);
 | 
			
		||||
        objects ~= compileSourceToObject(source, force);
 | 
			
		||||
    }
 | 
			
		||||
    string elfFile = linkObjects(objects);
 | 
			
		||||
    string hexFile = copyToHex(elfFile);
 | 
			
		||||
    writefln!"Built %s"(hexFile);
 | 
			
		||||
    runOrQuit("avr-size " ~ hexFile);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -70,11 +76,34 @@ void runOrQuit(string shellCommand, int[] successExitCodes = [0]) {
 | 
			
		|||
    if (!canFind(successExitCodes, result)) exit(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string compileSourceToObject(string sourcePath) {
 | 
			
		||||
void quitIfNonZero(int n) {
 | 
			
		||||
    import core.stdc.stdlib : exit;
 | 
			
		||||
    if (n != 0) exit(n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool shouldCompileSource(string sourcePath) {
 | 
			
		||||
    string name = baseName(sourcePath);
 | 
			
		||||
    name = name[0 .. name.lastIndexOf('.')];
 | 
			
		||||
    string hashPath = buildPath("bin", "hash", name ~ ".md5");
 | 
			
		||||
    string objectPath = buildPath("bin", name ~ ".o");
 | 
			
		||||
    if (!exists(hashPath) || !exists(objectPath)) return true;
 | 
			
		||||
    ubyte[] storedHash = Base64.decode(readText(hashPath).strip());
 | 
			
		||||
    ubyte[16] currentHash = md5Of(readText(sourcePath));
 | 
			
		||||
    return storedHash != currentHash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string compileSourceToObject(string sourcePath, bool force = false) {
 | 
			
		||||
    string flags = join(COMPILER_FLAGS, " ");
 | 
			
		||||
    string name = baseName(sourcePath);
 | 
			
		||||
    name = name[0 .. name.lastIndexOf('.')];
 | 
			
		||||
    string objectPath = buildPath("bin", name ~ ".o");
 | 
			
		||||
    string hashPath = buildPath("bin", "hash", name ~ ".md5");
 | 
			
		||||
 | 
			
		||||
    if (!force && !shouldCompileSource(sourcePath)) {
 | 
			
		||||
        writefln!"Not compiling %s because no changes detected."(sourcePath);
 | 
			
		||||
        return objectPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    string cmd = format!"avr-gcc %s -DF_CPU=%dUL -mmcu=%s -c -o %s %s"(
 | 
			
		||||
        flags,
 | 
			
		||||
        CPU_FREQ,
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +113,12 @@ string compileSourceToObject(string sourcePath) {
 | 
			
		|||
    );
 | 
			
		||||
    writeln(cmd);
 | 
			
		||||
    runOrQuit(cmd);
 | 
			
		||||
 | 
			
		||||
    ubyte[16] hash = md5Of(readText(sourcePath));
 | 
			
		||||
    string hashDir = buildPath("bin", "hash");
 | 
			
		||||
    if (!exists(hashDir)) mkdir(hashDir);
 | 
			
		||||
    std.file.write(hashPath, Base64.encode(hash));
 | 
			
		||||
 | 
			
		||||
    return objectPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
#include "spi.h"
 | 
			
		||||
 | 
			
		||||
void spi_initMaster() {
 | 
			
		||||
    SPI_DDR = (
 | 
			
		||||
        (1 << SPI_MOSI) |
 | 
			
		||||
        (1 << SPI_SCK)
 | 
			
		||||
    );
 | 
			
		||||
    SPCR = (
 | 
			
		||||
        (1 << SPE) |
 | 
			
		||||
        (1 << MSTR) |
 | 
			
		||||
        (1 << SPR0)
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void spi_initSlave() {
 | 
			
		||||
    SPI_DDR = (1 << SPI_MISO);
 | 
			
		||||
    SPCR = (1 << SPE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void spi_masterTransmit(uint8_t data) {
 | 
			
		||||
    SPDR = data;
 | 
			
		||||
    while (!(SPSR & (1 << SPIF))) {
 | 
			
		||||
        // Loop until we confirm transmission is done.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t spi_slaveReceive() {
 | 
			
		||||
    while (!(SPSR & (1 << SPIF))) {
 | 
			
		||||
        // Loop until SPI status is done.
 | 
			
		||||
    }
 | 
			
		||||
    return SPDR;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
#ifndef SPI_H
 | 
			
		||||
#define SPI_H
 | 
			
		||||
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
 | 
			
		||||
#define SPI_DDR DDRB
 | 
			
		||||
#define SPI_SCK DDB5
 | 
			
		||||
#define SPI_MISO DDB4
 | 
			
		||||
#define SPI_MOSI DDB3
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Initializes this device as an SPI master.
 | 
			
		||||
 */
 | 
			
		||||
void spi_initMaster();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Initializes this device as an SPI slave. 
 | 
			
		||||
 */
 | 
			
		||||
void spi_initSlave();
 | 
			
		||||
 | 
			
		||||
/** 
 | 
			
		||||
 * @brief Transmits a single byte of data to the currently selected slave
 | 
			
		||||
 * device. Blocks until transmission is complete.
 | 
			
		||||
 */
 | 
			
		||||
void spi_masterTransmit(uint8_t data);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Receives a single byte of data from a connected master. Blocks
 | 
			
		||||
 * until the receive is complete.
 | 
			
		||||
 */
 | 
			
		||||
uint8_t spi_slaveReceive();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in New Issue