Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
-Bug: WritePinValue

New:
- SPI examle for MCP23S17
  • Loading branch information
pi authored and pi committed Jul 8, 2014
1 parent 1d921bb commit ec9b908
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 51 deletions.
124 changes: 124 additions & 0 deletions bananaIO/MCP23S17Example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <stdint.h>
#include <unistd.h>

#include "src/bananaIO.h"

#define PIN_CLOCK PIN12 // Serial-Clock
#define PIN_MOSI PIN18 // Master-Out-Slave-In
#define PIN_MISO PIN16 // Master-In-Slave-Out
#define PIN_CS PIN22 // Chip-Select



#define MCP23S17_CONTROL_FIXED 0b01000000
#define MCP23S17_CONTROL_WRITE 0
#define MCP23S17_CONTROL_READ 1

#define MCP23S17_REGISTER_PORT_A_DIRECTION 0x00
#define MCP23S17_REGISTER_PORT_B_DIRECTION 0x01

#define MCP23S17_REGISTER_PORT_A_INTERRUPT 0x04
#define MCP23S17_REGISTER_PORT_B_INTERRUPT 0x05

#define MCP23S17_REGISTER_PORT_A_PULLMODE 0x0C
#define MCP23S17_REGISTER_PORT_B_PULLMODE 0x0D

#define MCP23S17_REGISTER_PORT_A 0x12
#define MCP23S17_REGISTER_PORT_B 0x13

#define MCP23S17_PORT_WRITE 0
#define MCP23S17_PORT_READ 1

#define MCP23S17_PORT_PULLNONE 0
#define MCP23S17_PORT_PULLUP 1

enum PortDirection {
PortDirectionOutput = 0,
PortDirectionInput = 1
};

void SpiSendByte(int value) {
int bitNumber = 0;
for (bitNumber; bitNumber < 8; bitNumber++) {

// send bit (high to low)
uint8_t x = ((value & 0x80) == 0x80);
digitalWrite(PIN_MOSI, x);

value <<= 1; // next bit. << because high to low

// high low on clock
digitalWrite(PIN_CLOCK, HIGH);
digitalWrite(PIN_CLOCK, LOW);


}

}

void SpiWrite(int address, int reg, int value) {

uint8_t control = MCP23S17_CONTROL_FIXED | address;

// start signal
digitalWrite(PIN_CS, LOW);

// send data ( control + register + value )
SpiSendByte(control);
SpiSendByte(reg);
SpiSendByte(value);

// end signal
digitalWrite(PIN_CS, HIGH);

}

void SpiConfigure(int address, enum PortDirection portDirection) {

digitalWrite(PIN_CS, HIGH);
digitalWrite(PIN_CLOCK, LOW);

SpiWrite(address, MCP23S17_REGISTER_PORT_A_DIRECTION, portDirection);
}

void Test() {

Initialize();

ConfigurePinDirection(PIN23, PinDirectionOutput);
WritePinValue(PIN23, 1);
WritePinValue(PIN23, 0);
WritePinValue(PIN23, 1);

newOutput(PIN23);

digitalWrite(PIN23, 0);
digitalWrite(PIN23, 1);

WritePinValue(PIN23,0);
WritePinValue(PIN23,1);



newOutput(PIN_CLOCK);
newOutput(PIN_MOSI);
newOutput(PIN_MISO);
newOutput(PIN_CS);

/*
pinMode(PIN_CLOCK, OUTPUT);
pinMode(PIN_CS, OUTPUT);
pinMode(PIN_MISO, OUTPUT);
pinMode(PIN_MOSI, OUTPUT);
*/

SpiConfigure(0, PortDirectionOutput);

int loopIndex = 0, value = 1;
for (loopIndex; loopIndex < 9; loopIndex++) {
SpiWrite(0, MCP23S17_REGISTER_PORT_A, value);
value = value << 1; // (loopIndex % 2);
sleep(1);
}

}
116 changes: 69 additions & 47 deletions bananaIO/src/bananaIO.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,21 @@
#include <fcntl.h>
#include <sys/mman.h>

#include "bananaIO.h"

#define PAGESIZE 4096
#define GPIO_BASE 0x01C20800 // A20 User Manual 2013-03-22.pdf

#define BYTE_PER_REGISTER 4 // All register are 32 Bit
#define PORT_SIZE 36 // Number of rows per port to calculate with uint32_t pointer

enum PinPullMode {
PinPullModeNone = 0b00,
PinPullModeUp = 0b01,
PinPullModeDown = 0b10
};

enum PinDirection {
PinDirectionInput = 0b000,
PinDirectionOutput = 0b001
};

enum PortRegister {
PortRegisterPullMode = 28,
PortRegisterMultiDriving = 20,
PortRegisterData = 16,
PortRegisterConfiguration = 0
};

enum Pins {
CON3_P03 = 149, PB21 = 149,
CON3_P05 = 148, PB20 = 148,
CON3_P07 = 1027, PI03 = 1027,
CON3_P08 = 896, PH00 = 896,
CON3_P10 = 897, PH01 = 897,
CON3_P11 = 1043, PI19 = 1043,
CON3_P12 = 898, PH02 = 898,
CON3_P13 = 1042, PI18 = 1042,
CON3_P15 = 1041, PI17 = 1041,
CON3_P16 = 916, PH20 = 916,
CON3_P18 = 917, PH21 = 917,
CON3_P19 = 1036, PI12 = 1036,
CON3_P21 = 1037, PI13 = 1037,
CON3_P22 = 1040, PI16 = 1040,
CON3_P23 = 1035, PI11 = 1035,
CON3_P24 = 1034, PI10 = 1034,
CON3_P26 = 1038, PI14 = 1038
};

struct Register {
// global settings
enum PortRegister PortRegister;
int PinsPerPort;
//int BitsPerRegister;
int PinsPerRegister;
int BitsPerPin;
};

volatile uint32_t *mappedMemory;

void Initialize() {
mappedMemory = openMemory();
}

volatile uint32_t *openMemory() {
int fileDescriptor;

Expand Down Expand Up @@ -138,6 +97,22 @@ int ReadPinValue(enum Pins pin) {
return pinValue;
}

int digitalRead(enum Pins pin)
{
return ReadPinValue(pin);
}

void digitalWrite(enum Pins pin, int value)
{
WritePinValue(pin, value);
}

void WritePinValue(enum Pins pin, int value) {
struct Register *configurationRegister = newRegister(PortRegisterData, 32, 1, 1);
WriteRegister(configurationRegister, pin, 1, value);
free(configurationRegister);
}

void ConfigurePinDirection(enum Pins pin, enum PinDirection pinDirection) {
struct Register *configurationRegister = newRegister(PortRegisterConfiguration, 32, 4, 4);
WriteRegister(configurationRegister, pin, 0b111, pinDirection);
Expand All @@ -150,8 +125,37 @@ void ConfigurePinPullMode(enum Pins pin, enum PinPullMode pullMode) {
free(configurationRegister);
}

struct InOut *newInputOutput(enum Pins pin, enum PinDirection pinDirection, enum PinPullMode pullMode) {

struct InOut *result;
if ((result = malloc(sizeof (struct InOut))) == NULL) {
return NULL;
}

ConfigurePinDirection(pin, pinDirection);
ConfigurePinPullMode(pin, pullMode);

result->Direction = pinDirection;
result->Pin = pin;
result->value = ReadPinValue(pin);

return result;

}

struct InOut *newInput(enum Pins pin, enum PinPullMode pullMode) {
return newInputOutput(pin, PinDirectionInput, pullMode);
}

struct InOut *newOutput(enum Pins pin) {
return newInputOutput(pin, PinDirectionOutput, PinPullModeNone);
}


void RegisterTest() {

int value;

mappedMemory = openMemory();
if (mappedMemory == NULL)
return;
Expand All @@ -163,7 +167,25 @@ void RegisterTest() {
ConfigurePinDirection(PH20, PinDirectionInput);
ConfigurePinPullMode(PH20, PinPullModeUp);

int value;


ConfigurePinDirection(PIN23, PinDirectionOutput);
WritePinValue(PIN23, 0);
value = ReadPinValue(PIN23);
WritePinValue(PIN23, 1);
value = ReadPinValue(PIN23);
WritePinValue(PIN23, 0);
value = ReadPinValue(PIN23);

// onboard LED - first echo gpio > /sys/class/leds/green\:ph24\:led1/trigger
ConfigurePinDirection(PH24, PinDirectionOutput);
WritePinValue(PH24, 0);
value = ReadPinValue(PH24);
WritePinValue(PH24, 1);
value = ReadPinValue(PH24);
WritePinValue(PH24, 0);
value = ReadPinValue(PH24);


// should be 1
value = ReadPinValue(PH02);
Expand Down
102 changes: 102 additions & 0 deletions bananaIO/src/bananaIO.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* File: bananaIO.h
* Author: pullrich
*
* Created on 8. Juli 2014, 12:30
*/

#ifndef BANANAIO_H
#define BANANAIO_H

#ifdef __cplusplus
extern "C" {
#endif


#define HIGH 1
#define LOW 0

enum PinPullMode {
PinPullModeNone = 0b00,
PinPullModeUp = 0b01,
PinPullModeDown = 0b10
};

enum PinDirection {
PinDirectionInput = 0b000,
PinDirectionOutput = 0b001
};

enum PortRegister {
PortRegisterPullMode = 28,
PortRegisterMultiDriving = 20,
PortRegisterData = 16,
PortRegisterConfiguration = 0
};

enum Pins {
PIN03 = 149, CON3_P03 = 149, PB21 = 149,
PIN05 = 148, CON3_P05 = 148, PB20 = 148,
PIN07 = 1027, CON3_P07 = 1027, PI03 = 1027,
PIN08 = 896, CON3_P08 = 896, PH00 = 896,
PIN10 = 897, CON3_P10 = 897, PH01 = 897,
PIN11 = 1043, CON3_P11 = 1043, PI19 = 1043,
PIN12 = 898, CON3_P12 = 898, PH02 = 898,
PIN13 = 1042, CON3_P13 = 1042, PI18 = 1042,
PIN15 = 1041, CON3_P15 = 1041, PI17 = 1041,
PIN16 = 916, CON3_P16 = 916, PH20 = 916,
PIN18 = 917, CON3_P18 = 917, PH21 = 917,
PIN19 = 1036, CON3_P19 = 1036, PI12 = 1036,
PIN21 = 1037, CON3_P21 = 1037, PI13 = 1037,
PIN22 = 1040, CON3_P22 = 1040, PI16 = 1040,
PIN23 = 1035, CON3_P23 = 1035, PI11 = 1035,
PIN24 = 1034, CON3_P24 = 1034, PI10 = 1034,
PIN26 = 1038, CON3_P26 = 1038, PI14 = 1038,

PH24 = 920

};

struct Register {
// global settings
enum PortRegister PortRegister;
int PinsPerPort;
//int BitsPerRegister;
int PinsPerRegister;
int BitsPerPin;
};

struct InOut {
enum Pins Pin;
enum PinDirection Direction;
int value;
};

volatile uint32_t *openMemory();

struct Register *newRegister(enum PortRegister portRegister, int bitsPerRegister, int bitsPerPin, int size);
void WriteRegister(struct Register *reg, enum Pins pin, int resetMask, int value);
int ReadRegister(struct Register *reg, enum Pins pin);

int ReadPinValue(enum Pins pin);
void WritePinValue(enum Pins pin, int value);

void digitalWrite(enum Pins pin, int value);
int digitalRead(enum Pins pin);

void ConfigurePinDirection(enum Pins pin, enum PinDirection pinDirection);
void ConfigurePinPullMode(enum Pins pin, enum PinPullMode pullMode);

struct InOut *newInputOutput(enum Pins pin, enum PinDirection pinDirection, enum PinPullMode pullMode);
struct InOut *newInput(enum Pins pin, enum PinPullMode pullMode);
struct InOut *newOutput(enum Pins pin);

void Initialize();


#ifdef __cplusplus
}
#endif

#endif /* BANANAIO_H */

Loading

0 comments on commit ec9b908

Please sign in to comment.