modify parallel epd run file
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
// blink.c
|
||||
//
|
||||
// Example program for bcm2835 library
|
||||
// Blinks a pin on an off every 0.5 secs
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o blink blink.c -l bcm2835
|
||||
// sudo ./blink
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o blink -I ../../src ../../src/bcm2835.c blink.c
|
||||
// sudo ./blink
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2011 Mike McCauley
|
||||
// $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Blinks on RPi Plug P1 pin 11 (which is GPIO pin 17)
|
||||
#define PIN RPI_GPIO_P1_11
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// If you call this, it will not actually access the GPIO
|
||||
// Use for testing
|
||||
// bcm2835_set_debug(1);
|
||||
|
||||
if (!bcm2835_init())
|
||||
return 1;
|
||||
|
||||
// Set the pin to be an output
|
||||
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
|
||||
|
||||
// Blink
|
||||
while (1)
|
||||
{
|
||||
// Turn it on
|
||||
bcm2835_gpio_write(PIN, HIGH);
|
||||
|
||||
// wait a bit
|
||||
bcm2835_delay(500);
|
||||
|
||||
// turn it off
|
||||
bcm2835_gpio_write(PIN, LOW);
|
||||
|
||||
// wait a bit
|
||||
bcm2835_delay(500);
|
||||
}
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -0,0 +1,57 @@
|
||||
// event.c
|
||||
//
|
||||
// Example program for bcm2835 library
|
||||
// Event detection of an input pin
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o event event.c -l bcm2835
|
||||
// sudo ./event
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o event -I ../../src ../../src/bcm2835.c event.c
|
||||
// sudo ./event
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2011 Mike McCauley
|
||||
// $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Input on RPi pin GPIO 15
|
||||
#define PIN RPI_GPIO_P1_15
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// If you call this, it will not actually access the GPIO
|
||||
// Use for testing
|
||||
// bcm2835_set_debug(1);
|
||||
|
||||
if (!bcm2835_init())
|
||||
return 1;
|
||||
|
||||
// Set RPI pin P1-15 to be an input
|
||||
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
|
||||
// with a pullup
|
||||
bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP);
|
||||
// And a low detect enable
|
||||
bcm2835_gpio_len(PIN);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (bcm2835_gpio_eds(PIN))
|
||||
{
|
||||
// Now clear the eds flag by setting it to 1
|
||||
bcm2835_gpio_set_eds(PIN);
|
||||
printf("low event detect for pin 15\n");
|
||||
}
|
||||
|
||||
// wait a bit
|
||||
delay(500);
|
||||
}
|
||||
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -0,0 +1,346 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* gpio.c
|
||||
*
|
||||
* Copyright (c) 2013 Shahrooz Shahparnia
|
||||
*
|
||||
* Description:
|
||||
* gpio is a command-line utility for executing gpio commands with the
|
||||
* Broadcom bcm2835. It was developed and tested on a Raspberry Pi single-board
|
||||
* computer model B. The utility is based on the bcm2835 C library developed
|
||||
* by Mike McCauley of Open System Consultants, http://www.open.com.au/mikem/bcm2835/.
|
||||
*
|
||||
* Invoking "gpio" results in a read, set of clear of a GPIO.
|
||||
* Options include GPIO read/set/clear
|
||||
* of a single GPIO pin, enabling or disabling pull up and pull downs as well as
|
||||
* resetting all GPIOs to a default input state.
|
||||
* The command usage and command-line parameters are described below
|
||||
* in the showusage function, which prints the usage if no command-line parameters
|
||||
* are included or if there are any command-line parameter errors. Invoking gpio
|
||||
* requires root privilege.
|
||||
*
|
||||
* This file contains the main function as well as functions for displaying
|
||||
* usage and for parsing the command line.
|
||||
*
|
||||
* Open Source Licensing GNU GPLv3
|
||||
*
|
||||
* Building:
|
||||
* After installing bcm2835, you can build this
|
||||
* with something like:
|
||||
* gcc -o gpio gpio.c -l bcm2835
|
||||
* sudo ./gpio
|
||||
*
|
||||
* Or you can test it before installing with:
|
||||
* gcc -o gpio -I ../../src ../../src/bcm2835.c gpio.c
|
||||
* sudo ./gpio
|
||||
*
|
||||
*
|
||||
* History:
|
||||
* 11/10 VERSION 1.0.0: Original
|
||||
*
|
||||
* User input parsing (comparse) and showusage\
|
||||
* have been adapted from: http://ipsolutionscorp.com/raspberry-pi-spi-utility/
|
||||
* mostly to keep consistence with the spincl tool usage.
|
||||
*
|
||||
* Compile with: gcc -o gpio gpio.c bcm2835.c
|
||||
*
|
||||
* Examples:
|
||||
* Clear pin 5: sudo ./gpio -ib -dc -pn -n5
|
||||
* Reset all GPIOs to inputs and disable all pull up/downs: sudo ./gpio -ie
|
||||
* Read pin 10: sudo ./gpio -ib -dr -pn -n10
|
||||
* Read pin 10 in debug mode with verbose output: sudo ./gpio -ib -dr -pn -n10 -b
|
||||
* Read pin 10 and set pin as input with pull down: sudo ./gpio -ib -di -pd -n10
|
||||
*
|
||||
* Note: Pin numbers match the Raspberry Pie connector pin numbers
|
||||
********************************************************************************/
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MODE_READ 0
|
||||
#define MODE_SET 1
|
||||
#define MODE_CLR 2
|
||||
#define MODE_INPUT_READ 3
|
||||
|
||||
#define PULL_UP 0
|
||||
#define PULL_DOWN 1
|
||||
#define NO_PULL 2
|
||||
|
||||
#define GPIO_BEGIN 0
|
||||
#define GPIO_END 1
|
||||
#define NO_ACTION 2
|
||||
|
||||
#define NO_PIN 40 // Some big number that's beyond the connector's pin count
|
||||
#define DEBUG_OFF 0
|
||||
#define DEBUG_ON 1
|
||||
|
||||
uint8_t init = NO_ACTION;
|
||||
uint8_t pull = NO_PULL;
|
||||
uint8_t mode = MODE_READ;
|
||||
uint8_t pin_number = NO_PIN;
|
||||
|
||||
uint8_t i, len;
|
||||
uint8_t data, pin, debug_mode = DEBUG_OFF;
|
||||
|
||||
//*******************************************************************************
|
||||
// comparse: Parse the command line and return EXIT_SUCCESS or EXIT_FAILURE
|
||||
// argc: number of command-line arguments
|
||||
// argv: array of command-line argument strings
|
||||
//*******************************************************************************
|
||||
|
||||
void gpio_reset(void);
|
||||
|
||||
int comparse(int argc, char **argv) {
|
||||
int argnum, i, xmitnum;
|
||||
|
||||
if (argc < 2) { // must have at least program name and len arguments
|
||||
// or -ie (GPIO_END) or -ib (GPIO_BEGIN)
|
||||
fprintf(stderr, "Insufficient command line arguments\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
argnum = 1;
|
||||
while (argnum < argc && argv[argnum][0] == '-') {
|
||||
|
||||
switch (argv[argnum][1]) {
|
||||
|
||||
case 'i': // GPIO init
|
||||
switch (argv[argnum][2]) {
|
||||
case 'b': init = GPIO_BEGIN; break;
|
||||
case 'e': init = GPIO_END; break;
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd': // Set/Clear/Read Mode
|
||||
switch (argv[argnum][2]) {
|
||||
case 'r': mode = MODE_READ; break;
|
||||
case 's': mode = MODE_SET; break;
|
||||
case 'c': mode = MODE_CLR; break;
|
||||
case 'i': mode = MODE_INPUT_READ; break;
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p': // Pull up, down and no pull Mode
|
||||
switch (argv[argnum][2]) {
|
||||
case 'u': pull = PULL_UP; break;
|
||||
case 'd': pull = PULL_DOWN; break;
|
||||
case 'n': pull = NO_PULL; break;
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n': // pin number
|
||||
pin_number = atoi(argv[argnum]+2);
|
||||
break;
|
||||
|
||||
case 'b': // debug mode
|
||||
debug_mode = DEBUG_ON;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid option\n", argv[argnum][1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
argnum++; // advance the argument number
|
||||
|
||||
}
|
||||
|
||||
if (argnum == argc && init != NO_ACTION) // no further arguments are needed
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
//*******************************************************************************
|
||||
// showusage: Print the usage statement and return errcode.
|
||||
//*******************************************************************************
|
||||
|
||||
int showusage(int errcode) {
|
||||
printf("gpio \n");
|
||||
printf("Usage: \n");
|
||||
printf(" gpio [options]\n");
|
||||
printf("\n");
|
||||
printf(" Invoking gpio to set or reset a GPIO, enable disable pull up or pull down. Initialize or release a GPIO.\n");
|
||||
printf("\n");
|
||||
printf(" The following are the options, which must be a single letter\n");
|
||||
printf(" preceded by a '-' and followed by another character.\n");
|
||||
printf(" -ix where x is the GPIO init option, b[egin] or e[nd]\n");
|
||||
printf(" The begin option must be executed before any transfer can happen.\n");
|
||||
printf(" The end option will return the GPIO to inputs and turn off all pull up and pull downs.\n");
|
||||
printf(" It may be included with a transfer.\n");
|
||||
printf(" -dx where x is 'c' for clear, 's' is for set, 'r' for read and 'i' for read and set as input.\n");
|
||||
printf(" -px where x is the GPIO pull up or down option. 'u' for pull up, 'd' for pull down and 'n' for none.\n");
|
||||
printf(" -nx where x is the pin number.\n");
|
||||
printf("\n");
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
printf("Running ... \n");
|
||||
|
||||
// parse the command line
|
||||
if (comparse(argc, argv) == EXIT_FAILURE) return showusage (EXIT_FAILURE);
|
||||
|
||||
if (!bcm2835_init()) return 1;
|
||||
|
||||
// GPIO begin if specified
|
||||
if (init == GPIO_BEGIN) ;
|
||||
|
||||
|
||||
// If len is 0, no need to continue, but do GPIO end if specified
|
||||
// if (len == 0) {
|
||||
// if (init == GPIO_END) ;
|
||||
// printf("Zero length ... error!\n");
|
||||
// return EXIT_SUCCESS;
|
||||
// }
|
||||
switch (pin_number) {
|
||||
case 3:
|
||||
pin = RPI_V2_GPIO_P1_03;
|
||||
break;
|
||||
case 5:
|
||||
pin = RPI_V2_GPIO_P1_05;
|
||||
break;
|
||||
case 7:
|
||||
pin = RPI_V2_GPIO_P1_07;
|
||||
break;
|
||||
case 26:
|
||||
pin = RPI_V2_GPIO_P1_26;
|
||||
break;
|
||||
case 24:
|
||||
pin = RPI_V2_GPIO_P1_24;
|
||||
break;
|
||||
case 21:
|
||||
pin = RPI_V2_GPIO_P1_21;
|
||||
break;
|
||||
case 19:
|
||||
pin = RPI_V2_GPIO_P1_19;
|
||||
break;
|
||||
case 23:
|
||||
pin = RPI_V2_GPIO_P1_23;
|
||||
break;
|
||||
case 10:
|
||||
pin = RPI_V2_GPIO_P1_10;
|
||||
break;
|
||||
case 11:
|
||||
pin = RPI_V2_GPIO_P1_11;
|
||||
break;
|
||||
case 12:
|
||||
pin = RPI_V2_GPIO_P1_12;
|
||||
break;
|
||||
case 13:
|
||||
pin = RPI_V2_GPIO_P1_13;
|
||||
break;
|
||||
case 15:
|
||||
pin = RPI_V2_GPIO_P1_15;
|
||||
break;
|
||||
case 16:
|
||||
pin = RPI_V2_GPIO_P1_16;
|
||||
break;
|
||||
case 18:
|
||||
pin = RPI_V2_GPIO_P1_18;
|
||||
break;
|
||||
case 22:
|
||||
pin = RPI_V2_GPIO_P1_22;
|
||||
break;
|
||||
default:
|
||||
pin = NO_PIN;
|
||||
}
|
||||
|
||||
switch (pull) {
|
||||
case PULL_UP:
|
||||
bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_UP);
|
||||
break;
|
||||
case PULL_DOWN:
|
||||
bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_DOWN);
|
||||
break;
|
||||
case NO_PULL:
|
||||
bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_OFF);
|
||||
break;
|
||||
default:
|
||||
bcm2835_gpio_set_pud(pin, BCM2835_GPIO_PUD_OFF);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case MODE_READ:
|
||||
data = bcm2835_gpio_lev(pin);
|
||||
printf("Reading pin: %d\n", data);
|
||||
break;
|
||||
case MODE_INPUT_READ:
|
||||
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
|
||||
data = bcm2835_gpio_lev(pin);
|
||||
printf("Reading pin: %d\n", data);
|
||||
break;
|
||||
case MODE_SET:
|
||||
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_set(pin);
|
||||
break;
|
||||
case MODE_CLR:
|
||||
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_clr(pin);
|
||||
break;
|
||||
default:
|
||||
printf("Wrong mode ...!\n");
|
||||
}
|
||||
|
||||
if (debug_mode == DEBUG_ON) {
|
||||
printf("Init %d\n", init);
|
||||
printf("Mode %d\n", mode);
|
||||
printf("Pull %d\n", pull);
|
||||
printf("Pin Number %d\n", pin_number);
|
||||
printf("Pin %d\n", pin);
|
||||
}
|
||||
|
||||
if (init == GPIO_END) gpio_reset();
|
||||
bcm2835_close();
|
||||
printf("... done!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_reset(void) {
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_03, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_05, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_07, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_26, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_24, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_21, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_19, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_23, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_10, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_11, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_12, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_13, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_15, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_16, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_18, BCM2835_GPIO_PUD_OFF);
|
||||
bcm2835_gpio_set_pud(RPI_V2_GPIO_P1_22, BCM2835_GPIO_PUD_OFF);
|
||||
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_07, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_10, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_11, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_12, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_13, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_15, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_16, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_18, BCM2835_GPIO_FSEL_INPT);
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_22, BCM2835_GPIO_FSEL_INPT);
|
||||
}
|
@@ -0,0 +1,278 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* i2c.c
|
||||
*
|
||||
* Copyright (c) 2013 Shahrooz Shahparnia (sshahrooz@gmail.com)
|
||||
*
|
||||
* Description:
|
||||
* i2c is a command-line utility for executing i2c commands with the
|
||||
* Broadcom bcm2835. It was developed and tested on a Raspberry Pi single-board
|
||||
* computer model B. The utility is based on the bcm2835 C library developed
|
||||
* by Mike McCauley of Open System Consultants, http://www.open.com.au/mikem/bcm2835/.
|
||||
*
|
||||
* Invoking spincl results in a read or write I2C transfer. Options include the
|
||||
* the I2C clock frequency, read/write, address, and port initialization/closing
|
||||
* procedures. The command usage and command-line parameters are described below
|
||||
* in the showusage function, which prints the usage if no command-line parameters
|
||||
* are included or if there are any command-line parameter errors. Invoking i2c
|
||||
* requires root privilege.
|
||||
*
|
||||
* This file contains the main function as well as functions for displaying
|
||||
* usage and for parsing the command line.
|
||||
*
|
||||
* Open Source Licensing GNU GPLv3
|
||||
*
|
||||
* Building:
|
||||
* After installing bcm2835, you can build this
|
||||
* with something like:
|
||||
* gcc -o i2c i2c.c -l bcm2835
|
||||
* sudo ./i2c
|
||||
*
|
||||
* Or you can test it before installing with:
|
||||
* gcc -o i2c -I ../../src ../../src/bcm2835.c i2c.c
|
||||
* sudo ./i2c
|
||||
*
|
||||
* History:
|
||||
* 11/05 VERSION 1.0.0: Original
|
||||
*
|
||||
* User input parsing (comparse) and showusage\
|
||||
* have been adapted from: http://ipsolutionscorp.com/raspberry-pi-spi-utility/
|
||||
* mostly to keep consistence with the spincl tool usage.
|
||||
*
|
||||
* Compile with: gcc -o i2c i2c.c bcm2835.c
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* Set up ADC (Arduino: ADC1015)
|
||||
* sudo ./i2c -s72 -dw -ib 3 0x01 0x44 0x00 (select config register, setup mux, etc.)
|
||||
* sudo ./i2c -s72 -dw -ib 1 0x00 (select ADC data register)
|
||||
*
|
||||
* Bias DAC (Arduino: MCP4725) at some voltage
|
||||
* sudo ./i2c -s99 -dw -ib 3 0x60 0x7F 0xF0 (FS output is with 0xFF 0xF0)
|
||||
* Read ADC convergence result
|
||||
* sudo ./i2c -s72 -dr -ib 2 (FS output is 0x7FF0 with PGA1 = 1)
|
||||
*
|
||||
* In a DAC to ADC loop back typical results are:
|
||||
*
|
||||
* DAC VOUT ADC
|
||||
* 7FFh 1.6V 677h Note ratio is FS_ADC*PGA_GAIN/FS_DAC = 4.096/3.3 = 1.23
|
||||
* 5FFh 1.2V 4DCh
|
||||
* 8F0h 1.8V 745h
|
||||
* 9D0h 2V 7EAh
|
||||
* 000h 10mV 004h
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MODE_READ 0
|
||||
#define MODE_WRITE 1
|
||||
|
||||
#define MAX_LEN 32
|
||||
|
||||
char wbuf[MAX_LEN];
|
||||
|
||||
typedef enum {
|
||||
NO_ACTION,
|
||||
I2C_BEGIN,
|
||||
I2C_END
|
||||
} i2c_init;
|
||||
|
||||
uint8_t init = NO_ACTION;
|
||||
uint16_t clk_div = BCM2835_I2C_CLOCK_DIVIDER_148;
|
||||
uint8_t slave_address = 0x00;
|
||||
uint32_t len = 0;
|
||||
uint8_t mode = MODE_READ;
|
||||
|
||||
//*******************************************************************************
|
||||
// comparse: Parse the command line and return EXIT_SUCCESS or EXIT_FAILURE
|
||||
// argc: number of command-line arguments
|
||||
// argv: array of command-line argument strings
|
||||
//*******************************************************************************
|
||||
|
||||
int comparse(int argc, char **argv) {
|
||||
int argnum, i, xmitnum;
|
||||
|
||||
if (argc < 2) { // must have at least program name and len arguments
|
||||
// or -ie (I2C_END) or -ib (I2C_BEGIN)
|
||||
fprintf(stderr, "Insufficient command line arguments\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
argnum = 1;
|
||||
while (argnum < argc && argv[argnum][0] == '-') {
|
||||
|
||||
switch (argv[argnum][1]) {
|
||||
|
||||
case 'i': // I2C init
|
||||
switch (argv[argnum][2]) {
|
||||
case 'b': init = I2C_BEGIN; break;
|
||||
case 'e': init = I2C_END; break;
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd': // Read/Write Mode
|
||||
switch (argv[argnum][2]) {
|
||||
case 'r': mode = MODE_READ; break;
|
||||
case 'w': mode = MODE_WRITE; break;
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid init option\n", argv[argnum][2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c': // Clock divider
|
||||
clk_div = atoi(argv[argnum]+2);
|
||||
break;
|
||||
|
||||
case 's': // Slave address
|
||||
slave_address = atoi(argv[argnum]+2);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%c is not a valid option\n", argv[argnum][1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
argnum++; // advance the argument number
|
||||
|
||||
}
|
||||
|
||||
// If command is used for I2C_END or I2C_BEGIN only
|
||||
if (argnum == argc && init != NO_ACTION) // no further arguments are needed
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
// Get len
|
||||
if (strspn(argv[argnum], "0123456789") != strlen(argv[argnum])) {
|
||||
fprintf(stderr, "Invalid number of bytes specified\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
len = atoi(argv[argnum]);
|
||||
|
||||
if (len > MAX_LEN) {
|
||||
fprintf(stderr, "Invalid number of bytes specified\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
argnum++; // advance the argument number
|
||||
|
||||
xmitnum = argc - argnum; // number of xmit bytes
|
||||
|
||||
memset(wbuf, 0, sizeof(wbuf));
|
||||
|
||||
for (i = 0; i < xmitnum; i++) {
|
||||
if (strspn(argv[argnum + i], "0123456789abcdefABCDEFxX") != strlen(argv[argnum + i])) {
|
||||
fprintf(stderr, "Invalid data: ");
|
||||
fprintf(stderr, "%d \n", xmitnum);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
wbuf[i] = (char)strtoul(argv[argnum + i], NULL, 0);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
//*******************************************************************************
|
||||
// showusage: Print the usage statement and return errcode.
|
||||
//*******************************************************************************
|
||||
int showusage(int errcode) {
|
||||
printf("i2c \n");
|
||||
printf("Usage: \n");
|
||||
printf(" i2c [options] len [rcv/xmit bytes]\n");
|
||||
printf("\n");
|
||||
printf(" Invoking i2c results in an I2C transfer of a specified\n");
|
||||
printf(" number of bytes. Additionally, it can be used to set the appropriate\n");
|
||||
printf(" GPIO pins to their respective I2C configurations or return them\n");
|
||||
printf(" to GPIO input configuration. Options include the I2C clock frequency,\n");
|
||||
printf(" initialization option (i2c_begin and i2c_end). i2c must be invoked\n");
|
||||
printf(" with root privileges.\n");
|
||||
printf("\n");
|
||||
printf(" The following are the options, which must be a single letter\n");
|
||||
printf(" preceded by a '-' and followed by another character.\n");
|
||||
printf(" -dx where x is 'w' for write and 'r' is for read.\n");
|
||||
printf(" -ix where x is the I2C init option, b[egin] or e[nd]\n");
|
||||
printf(" The begin option must be executed before any transfer can happen.\n");
|
||||
printf(" It may be included with a transfer.\n");
|
||||
printf(" The end option will return the I2C pins to GPIO inputs.\n");
|
||||
printf(" It may be included with a transfer.\n");
|
||||
printf(" -cx where x is the clock divider from 250MHz. Allowed values\n");
|
||||
printf(" are 150 through 2500.\n");
|
||||
printf(" Corresponding frequencies are specified in bcm2835.h.\n");
|
||||
printf("\n");
|
||||
printf(" len: The number of bytes to be transmitted or received.\n");
|
||||
printf(" The maximum number of bytes allowed is %d\n", MAX_LEN);
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
return errcode;
|
||||
}
|
||||
|
||||
char buf[MAX_LEN];
|
||||
int i;
|
||||
uint8_t data;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
printf("Running ... \n");
|
||||
|
||||
// parse the command line
|
||||
if (comparse(argc, argv) == EXIT_FAILURE) return showusage (EXIT_FAILURE);
|
||||
|
||||
if (!bcm2835_init())
|
||||
{
|
||||
printf("bcm2835_init failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// I2C begin if specified
|
||||
if (init == I2C_BEGIN)
|
||||
{
|
||||
if (!bcm2835_i2c_begin())
|
||||
{
|
||||
printf("bcm2835_i2c_begin failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If len is 0, no need to continue, but do I2C end if specified
|
||||
if (len == 0) {
|
||||
if (init == I2C_END) bcm2835_i2c_end();
|
||||
printf("... done!\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
bcm2835_i2c_setSlaveAddress(slave_address);
|
||||
bcm2835_i2c_setClockDivider(clk_div);
|
||||
fprintf(stderr, "Clock divider set to: %d\n", clk_div);
|
||||
fprintf(stderr, "len set to: %d\n", len);
|
||||
fprintf(stderr, "Slave address set to: %d\n", slave_address);
|
||||
|
||||
if (mode == MODE_READ) {
|
||||
for (i=0; i<MAX_LEN; i++) buf[i] = 'n';
|
||||
data = bcm2835_i2c_read(buf, len);
|
||||
printf("Read Result = %d\n", data);
|
||||
for (i=0; i<MAX_LEN; i++) {
|
||||
if(buf[i] != 'n') printf("Read Buf[%d] = %x\n", i, buf[i]);
|
||||
}
|
||||
}
|
||||
if (mode == MODE_WRITE) {
|
||||
data = bcm2835_i2c_write(wbuf, len);
|
||||
printf("Write Result = %d\n", data);
|
||||
}
|
||||
|
||||
// This I2C end is done after a transfer if specified
|
||||
if (init == I2C_END) bcm2835_i2c_end();
|
||||
bcm2835_close();
|
||||
printf("... done!\n");
|
||||
return 0;
|
||||
}
|
||||
|
@@ -0,0 +1,53 @@
|
||||
// input.c
|
||||
//
|
||||
// Example program for bcm2835 library
|
||||
// Reads and prints the state of an input pin
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o input input.c -l bcm2835
|
||||
// sudo ./input
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o input -I ../../src ../../src/bcm2835.c input.c
|
||||
// sudo ./input
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2011 Mike McCauley
|
||||
// $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Input on RPi pin GPIO 15
|
||||
#define PIN RPI_GPIO_P1_15
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// If you call this, it will not actually access the GPIO
|
||||
// Use for testing
|
||||
// bcm2835_set_debug(1);
|
||||
|
||||
if (!bcm2835_init())
|
||||
return 1;
|
||||
|
||||
// Set RPI pin P1-15 to be an input
|
||||
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
|
||||
// with a pullup
|
||||
bcm2835_gpio_set_pud(PIN, BCM2835_GPIO_PUD_UP);
|
||||
|
||||
// Blink
|
||||
while (1)
|
||||
{
|
||||
// Read some data
|
||||
uint8_t value = bcm2835_gpio_lev(PIN);
|
||||
printf("read from pin 15: %d\n", value);
|
||||
|
||||
// wait a bit
|
||||
delay(500);
|
||||
}
|
||||
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -0,0 +1,66 @@
|
||||
// pwm.c
|
||||
//
|
||||
// Example program for bcm2835 library
|
||||
// Shows how to use PWM to control GPIO pins
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o pwm pwm.c -l bcm2835
|
||||
// sudo ./pwm
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o pwm -I ../../src ../../src/bcm2835.c pwm.c
|
||||
// sudo ./pwm
|
||||
//
|
||||
// Connect an LED between GPIO18 (pin 12) and GND to observe the LED changing in brightness
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2013 Mike McCauley
|
||||
// $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// PWM output on RPi Plug P1 pin 12 (which is GPIO pin 18)
|
||||
// in alt fun 5.
|
||||
// Note that this is the _only_ PWM pin available on the RPi IO headers
|
||||
#define PIN RPI_GPIO_P1_12
|
||||
// and it is controlled by PWM channel 0
|
||||
#define PWM_CHANNEL 0
|
||||
// This controls the max range of the PWM signal
|
||||
#define RANGE 1024
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (!bcm2835_init())
|
||||
return 1;
|
||||
|
||||
// Set the output pin to Alt Fun 5, to allow PWM channel 0 to be output there
|
||||
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_ALT5);
|
||||
|
||||
// Clock divider is set to 16.
|
||||
// With a divider of 16 and a RANGE of 1024, in MARKSPACE mode,
|
||||
// the pulse repetition frequency will be
|
||||
// 1.2MHz/1024 = 1171.875Hz, suitable for driving a DC motor with PWM
|
||||
bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_16);
|
||||
bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1);
|
||||
bcm2835_pwm_set_range(PWM_CHANNEL, RANGE);
|
||||
|
||||
// Vary the PWM m/s ratio between 1/RANGE and (RANGE-1)/RANGE
|
||||
// over the course of a a few seconds
|
||||
int direction = 1; // 1 is increase, -1 is decrease
|
||||
int data = 1;
|
||||
while (1)
|
||||
{
|
||||
if (data == 1)
|
||||
direction = 1; // Switch to increasing
|
||||
else if (data == RANGE-1)
|
||||
direction = -1; // Switch to decreasing
|
||||
data += direction;
|
||||
bcm2835_pwm_set_data(PWM_CHANNEL, data);
|
||||
bcm2835_delay(1);
|
||||
}
|
||||
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
// spi.c
|
||||
//
|
||||
// Example program for bcm2835 library
|
||||
// Shows how to interface with SPI to transfer a byte to and from an SPI device
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o spi spi.c -l bcm2835
|
||||
// sudo ./spi
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o spi -I ../../src ../../src/bcm2835.c spi.c
|
||||
// sudo ./spi
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2012 Mike McCauley
|
||||
// $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// If you call this, it will not actually access the GPIO
|
||||
// Use for testing
|
||||
// bcm2835_set_debug(1);
|
||||
|
||||
if (!bcm2835_init())
|
||||
{
|
||||
printf("bcm2835_init failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bcm2835_spi_begin())
|
||||
{
|
||||
printf("bcm2835_spi_begin failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default
|
||||
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default
|
||||
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
|
||||
bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default
|
||||
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default
|
||||
|
||||
// Send a byte to the slave and simultaneously read a byte back from the slave
|
||||
// If you tie MISO to MOSI, you should read back what was sent
|
||||
uint8_t send_data = 0x23;
|
||||
uint8_t read_data = bcm2835_spi_transfer(send_data);
|
||||
printf("Sent to SPI: 0x%02X. Read back from SPI: 0x%02X.\n", send_data, read_data);
|
||||
if (send_data != read_data)
|
||||
printf("Do you have the loopback from MOSI to MISO connected?\n");
|
||||
bcm2835_spi_end();
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -0,0 +1,63 @@
|
||||
// spin.c
|
||||
//
|
||||
// Example program for bcm2835 library
|
||||
// Shows how to interface with SPI to transfer a number of bytes to and from an SPI device
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o spin spin.c -l bcm2835
|
||||
// sudo ./spin
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o spin -I ../../src ../../src/bcm2835.c spin.c
|
||||
// sudo ./spin
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2012 Mike McCauley
|
||||
// $Id: RF22.h,v 1.21 2012/05/30 01:51:25 mikem Exp $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// If you call this, it will not actually access the GPIO
|
||||
// Use for testing
|
||||
// bcm2835_set_debug(1);
|
||||
|
||||
if (!bcm2835_init())
|
||||
{
|
||||
printf("bcm2835_init failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bcm2835_spi_begin())
|
||||
{
|
||||
printf("bcm2835_spi_begin failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
bcm2835_spi_begin();
|
||||
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default
|
||||
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default
|
||||
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
|
||||
bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default
|
||||
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default
|
||||
|
||||
// Send a some bytes to the slave and simultaneously read
|
||||
// some bytes back from the slave
|
||||
// Most SPI devices expect one or 2 bytes of command, after which they will send back
|
||||
// some data. In such a case you will have the command bytes first in the buffer,
|
||||
// followed by as many 0 bytes as you expect returned data bytes. After the transfer, you
|
||||
// Can the read the reply bytes from the buffer.
|
||||
// If you tie MISO to MOSI, you should read back what was sent.
|
||||
|
||||
char buf[] = { 0x01, 0x02, 0x11, 0x33 }; // Data to send
|
||||
bcm2835_spi_transfern(buf, sizeof(buf));
|
||||
// buf will now be filled with the data that was read from the slave
|
||||
printf("Read from SPI: %02X %02X %02X %02X \n", buf[0], buf[1], buf[2], buf[3]);
|
||||
|
||||
bcm2835_spi_end();
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -0,0 +1,92 @@
|
||||
// spiram.c
|
||||
//
|
||||
// Little library for accessing SPI RAM such as 23K256-I/P
|
||||
// using bcm2835 library on Raspberry Pi
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2018 Mike McCauley
|
||||
// This software is part of the bcm2835 library and is licensed under the same conditions
|
||||
// $Id: $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <string.h> // memcpy
|
||||
#include "spiram.h"
|
||||
|
||||
static uint8_t _mode = SPIRAM_MODE_INVALID;
|
||||
|
||||
uint8_t spiram_read_sr()
|
||||
{
|
||||
uint8_t command[] = { SPIRAM_OPCODE_READ_SR, 0};
|
||||
bcm2835_spi_transfern(command, sizeof(command));
|
||||
return command[1];
|
||||
}
|
||||
|
||||
bool spiram_write_sr(uint8_t value)
|
||||
{
|
||||
uint8_t command[] = { SPIRAM_OPCODE_WRITE_SR, value};
|
||||
bcm2835_spi_transfern(command, sizeof(command));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spiram_set_mode(uint8_t mode)
|
||||
{
|
||||
if (mode != _mode)
|
||||
{
|
||||
spiram_write_sr(mode);
|
||||
_mode = mode;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spiram_begin()
|
||||
{
|
||||
_mode = SPIRAM_MODE_BYTE;
|
||||
|
||||
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default
|
||||
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default
|
||||
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
|
||||
bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default
|
||||
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spiram_end()
|
||||
{
|
||||
bcm2835_spi_end();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t spiram_read_byte(uint16_t address)
|
||||
{
|
||||
spiram_set_mode(SPIRAM_MODE_BYTE);
|
||||
uint8_t command[] = { SPIRAM_OPCODE_READ, (address >> 8) & 0xff, address & 0xff, 0xff };
|
||||
bcm2835_spi_transfern(command, sizeof(command));
|
||||
uint8_t ret = command[3];
|
||||
}
|
||||
|
||||
bool spiram_write_byte(uint16_t address, uint8_t value)
|
||||
{
|
||||
spiram_set_mode(SPIRAM_MODE_BYTE);
|
||||
uint8_t command[] = { SPIRAM_OPCODE_WRITE, (address >> 8) & 0xff, address & 0xff, value };
|
||||
bcm2835_spi_writenb(command, sizeof(command));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spiram_read_page(uint16_t address, uint8_t *buf)
|
||||
{
|
||||
spiram_set_mode(SPIRAM_MODE_PAGE);
|
||||
uint8_t command[3 + SPIRAM_PAGE_SIZE] = { SPIRAM_OPCODE_READ, (address >> 8) & 0xff, address & 0xff };
|
||||
bcm2835_spi_transfern(command, sizeof(command));
|
||||
memcpy(buf, command + 3, SPIRAM_PAGE_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spiram_write_page(uint16_t address, uint8_t *buf)
|
||||
{
|
||||
spiram_set_mode(SPIRAM_MODE_PAGE);
|
||||
uint8_t command[3 + SPIRAM_PAGE_SIZE] = { SPIRAM_OPCODE_WRITE, (address >> 8) & 0xff, address & 0xff };
|
||||
memcpy(command + 3, buf, SPIRAM_PAGE_SIZE);;
|
||||
bcm2835_spi_writenb(command, sizeof(command));
|
||||
return true;
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
// spiram.h
|
||||
//
|
||||
// Header for a Little Library for accessing SPI RAM chips such as 23K256-I/P
|
||||
// using bcm2835 library on Raspberry Pi
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2018 Mike McCauley
|
||||
// This software is part of the bcm2835 library and is licensed under the same conditions
|
||||
// $Id: $
|
||||
|
||||
#include <stdbool.h> // bool, true, false
|
||||
|
||||
#ifndef SPIRAM_h
|
||||
#define SPIRAM_h
|
||||
|
||||
#define SPIRAM_HOLD_DISABLE 0x1
|
||||
#define SPIRAM_MODE_BYTE (0x00 | SPIRAM_HOLD_DISABLE)
|
||||
#define SPIRAM_MODE_PAGE (0x80 | SPIRAM_HOLD_DISABLE)
|
||||
#define SPIRAM_MODE_STREAM (0x40 | SPIRAM_HOLD_DISABLE)
|
||||
#define SPIRAM_MODE_INVALID 0xff
|
||||
#define SPIRAM_OPCODE_READ_SR 0x05
|
||||
#define SPIRAM_OPCODE_WRITE_SR 0x01
|
||||
#define SPIRAM_OPCODE_READ 0x03
|
||||
#define SPIRAM_OPCODE_WRITE 0x02
|
||||
|
||||
/* Size of a page in 23K256 */
|
||||
#define SPIRAM_PAGE_SIZE 32
|
||||
|
||||
/*
|
||||
* This library allows you to read and write data from an external SPI interfaced static ram (SRAM)
|
||||
* such as 23K256 (256kbit = 32kByte)
|
||||
* Byte and POage modes are supported.
|
||||
* Valid addresses are from 0x0000 to 0x7fff
|
||||
* Tested on RPI 3 Model B, Raspbian Jessie
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialise the spiram library, enables SPI with default divider of
|
||||
* BCM2835_SPI_CLOCK_DIVIDER_65536 = 6.1035156kHz on RPI3.
|
||||
* You can change the SPI speed after calling this by calling bcm2835_spi_setClockDivider()
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_begin();
|
||||
|
||||
/*
|
||||
* Stops using the RPI SPI functions and returns the GPIO pins to their default behaviour.
|
||||
* Call this when you have finished using SPI forever, or at the end of your program
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_end();
|
||||
|
||||
/*
|
||||
* Read and returns the current value of the SRAM status register
|
||||
*/
|
||||
uint8_t spiram_read_sr();
|
||||
|
||||
/*
|
||||
* Write a new value to the SRAM status register,
|
||||
* usually one of SPIRAM_MODE_*
|
||||
* You should never need to call this directly. Used internally.
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_write_sr(uint8_t value);
|
||||
|
||||
/*
|
||||
* Set the operating mode of the SRAM.
|
||||
* Mode is one of SPIRAM_MODE_*. THis is done automatically
|
||||
* by the spiram_write_* and spiram_read_* functions, so you would not normally
|
||||
* need to call this directly.
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_set_mode(uint8_t mode);
|
||||
|
||||
/*
|
||||
* Reads a single byte from the given address and returns it.
|
||||
*/
|
||||
uint8_t spiram_read_byte(uint16_t address);
|
||||
|
||||
/*
|
||||
* Writes a single byte to the given address.
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_write_byte(uint16_t address, uint8_t value);
|
||||
|
||||
/*
|
||||
* Reads a whole page of data (32 bytes) from the page starting at the given address.
|
||||
* The read data is placed in buf. Be sure that there is enough rom there for it.
|
||||
* Caution: if the starting address is not on a page boundary,
|
||||
* it will wrap back to the beginning of the page.
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_read_page(uint16_t address, uint8_t *buf);
|
||||
|
||||
/*
|
||||
* Writes a whole page of data (32 bytes) to the page starting at the given address.
|
||||
* Caution: if the starting address is not on a page boundary,
|
||||
* it will wrap back to the beginning of the page.
|
||||
* Returns true on success, false otherwise
|
||||
*/
|
||||
bool spiram_write_page(uint16_t address, uint8_t *buf);
|
||||
|
||||
#endif
|
@@ -0,0 +1,99 @@
|
||||
// spiram_test.c
|
||||
//
|
||||
// Example program for bcm2835
|
||||
// Shows how to interface with SPI RAM such as 23K256-I/P
|
||||
// using the spiram little library
|
||||
//
|
||||
// Tested on RPI 3 Model B, Raspbian Jessie
|
||||
// Tested at full speed over many hours with no errors.
|
||||
//
|
||||
// Connect RPi 3 B to 23K256-I/P like this:
|
||||
// RPi pin Function 23K256-I/P pin (name)
|
||||
// J1-6 GND 4 (VSS)
|
||||
// J1-1 3.3V 8 (VCC)
|
||||
// and 7 (/HOLD)
|
||||
// J1-19 SPI0_MOSI 5 (SI)
|
||||
// J1-21 SPI0_MISO 2 (SO)
|
||||
// J1-23 SPI0_SCLK 6 (SCK)
|
||||
// J1-24 SPI0_CE0_N 1 (/CS)
|
||||
//
|
||||
// After installing bcm2835, you can build this
|
||||
// with something like:
|
||||
// gcc -o spiram_test spiram.c spiram_test.c -l bcm2835
|
||||
// sudo ./spiram_test
|
||||
//
|
||||
// Or you can test it before installing with:
|
||||
// gcc -o spiram_test -I ../../src ../../src/bcm2835.c spiram.c spiram_test.c
|
||||
// sudo ./spiram_test
|
||||
//
|
||||
// Author: Mike McCauley
|
||||
// Copyright (C) 2018 Mike McCauley
|
||||
// $Id: $
|
||||
|
||||
#include <bcm2835.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h> // memcmp
|
||||
#include "spiram.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (!bcm2835_init())
|
||||
{
|
||||
printf("bcm2835_init failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!bcm2835_spi_begin())
|
||||
{
|
||||
printf("bcm2835_spi_begin failed. Are you running as root??\n");
|
||||
return 1;
|
||||
}
|
||||
if (!spiram_begin())
|
||||
{
|
||||
printf("spiram_begin failed.\n");
|
||||
return 1;
|
||||
}
|
||||
/* You can speed things up by selecting a faster SPI speed
|
||||
// after spiram_begin, which defaults to BCM2835_SPI_CLOCK_DIVIDER_65536 = 6.1035156kHz on RPI3
|
||||
*/
|
||||
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_64); // 6.25MHz on RPI3
|
||||
|
||||
uint8_t value = 0;
|
||||
uint16_t address = 0x0000;
|
||||
while (1)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
/* ret = spiram_read_sr();*/
|
||||
spiram_write_byte(address, value);
|
||||
ret = spiram_read_byte(address);
|
||||
if (ret != value)
|
||||
printf("ERROR: spiram_read_byte address %04x got %02x, expected %02x\n", address, ret, value);
|
||||
#if 0
|
||||
printf("spiram_read_byte at address %04x got %02x\n", address, ret);
|
||||
#endif
|
||||
|
||||
uint8_t write_page_buf[SPIRAM_PAGE_SIZE] = { 0, value, value, value };
|
||||
uint8_t read_page_buf[SPIRAM_PAGE_SIZE];
|
||||
spiram_write_page(address, write_page_buf);
|
||||
|
||||
spiram_read_page(address, read_page_buf);
|
||||
if (memcmp(write_page_buf, read_page_buf, SPIRAM_PAGE_SIZE) != 0)
|
||||
printf("ERROR: spiram_read_page at address %04x\n", address);
|
||||
#if 0
|
||||
printf("spiram_read_page address %04x got ", address);
|
||||
int i;
|
||||
for (i = 0; i < SPIRAM_PAGE_SIZE; i++)
|
||||
printf("%02x ", read_page_buf[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
/* sleep(1); */
|
||||
value++;
|
||||
address++;
|
||||
}
|
||||
|
||||
spiram_end();
|
||||
bcm2835_close();
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user