/* bcm2835.c
// C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi
// http://elinux.org/RPi_Low-level_peripherals
// http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
//
// Author: Mike McCauley
// Copyright (C) 2011-2013 Mike McCauley
// $Id: bcm2835.c,v 1.25 2018/01/16 21:55:07 mikem Exp mikem $
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#define BCK2835_LIBRARY_BUILD
#include "bcm2835.h"
/* This define enables a little test program (by default a blinking output on pin RPI_GPIO_PIN_11)
// You can do some safe, non-destructive testing on any platform with:
// gcc bcm2835.c -D BCM2835_TEST
// ./a.out
*/
/*#define BCM2835_TEST*/
/* Uncommenting this define compiles alternative I2C code for the version 1 RPi
// The P1 header I2C pins are connected to SDA0 and SCL0 on V1.
// By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected.
*/
/* #define I2C_V1*/
/* Physical address and size of the peripherals block
// May be overridden on RPi2
*/
uint32_t *bcm2835_peripherals_base = (uint32_t *)BCM2835_PERI_BASE;
uint32_t bcm2835_peripherals_size = BCM2835_PERI_SIZE;
/* Virtual memory address of the mapped peripherals block
*/
uint32_t *bcm2835_peripherals = (uint32_t *)MAP_FAILED;
/* And the register bases within the peripherals block
*/
volatile uint32_t *bcm2835_gpio = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_pwm = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_clk = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_pads = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_spi0 = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_bsc0 = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_bsc1 = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_st = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_aux = (uint32_t *)MAP_FAILED;
volatile uint32_t *bcm2835_spi1 = (uint32_t *)MAP_FAILED;
/* This variable allows us to test on hardware other than RPi.
// It prevents access to the kernel memory, and does not do any peripheral access
// Instead it prints out what it _would_ do if debug were 0
*/
static uint8_t debug = 0;
/* I2C The time needed to transmit one byte. In microseconds.
*/
static int i2c_byte_wait_us = 0;
/* SPI bit order. BCM2835 SPI0 only supports MSBFIRST, so we instead
* have a software based bit reversal, based on a contribution by Damiano Benedetti
*/
static uint8_t bcm2835_spi_bit_order = BCM2835_SPI_BIT_ORDER_MSBFIRST;
static uint8_t bcm2835_byte_reverse_table[] =
{
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
static uint8_t bcm2835_correct_order(uint8_t b)
{
if (bcm2835_spi_bit_order == BCM2835_SPI_BIT_ORDER_LSBFIRST)
return bcm2835_byte_reverse_table[b];
else
return b;
}
/*
// Low level register access functions
*/
/* Function to return the pointers to the hardware register bases */
uint32_t* bcm2835_regbase(uint8_t regbase)
{
switch (regbase)
{
case BCM2835_REGBASE_ST:
return (uint32_t *)bcm2835_st;
case BCM2835_REGBASE_GPIO:
return (uint32_t *)bcm2835_gpio;
case BCM2835_REGBASE_PWM:
return (uint32_t *)bcm2835_pwm;
case BCM2835_REGBASE_CLK:
return (uint32_t *)bcm2835_clk;
case BCM2835_REGBASE_PADS:
return (uint32_t *)bcm2835_pads;
case BCM2835_REGBASE_SPI0:
return (uint32_t *)bcm2835_spi0;
case BCM2835_REGBASE_BSC0:
return (uint32_t *)bcm2835_bsc0;
case BCM2835_REGBASE_BSC1:
return (uint32_t *)bcm2835_st;
case BCM2835_REGBASE_AUX:
return (uint32_t *)bcm2835_aux;
case BCM2835_REGBASE_SPI1:
return (uint32_t *)bcm2835_spi1;
}
return (uint32_t *)MAP_FAILED;
}
void bcm2835_set_debug(uint8_t d)
{
debug = d;
}
unsigned int bcm2835_version(void)
{
return BCM2835_VERSION;
}
/* Read with memory barriers from peripheral
*
*/
uint32_t bcm2835_peri_read(volatile uint32_t* paddr)
{
uint32_t ret;
if (debug)
{
printf("bcm2835_peri_read paddr %p\n", (void *) paddr);
return 0;
}
else
{
__sync_synchronize();
ret = *paddr;
__sync_synchronize();
return ret;
}
}
/* read from peripheral without the read barrier
* This can only be used if more reads to THE SAME peripheral
* will follow. The sequence must terminate with memory barrier
* before any read or write to another peripheral can occur.
* The MB can be explicit, or one of the barrier read/write calls.
*/
uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr)
{
if (debug)
{
printf("bcm2835_peri_read_nb paddr %p\n", paddr);
return 0;
}
else
{
return *paddr;
}
}
/* Write with memory barriers to peripheral
*/
void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value)
{
if (debug)
{
printf("bcm2835_peri_write paddr %p, value %08X\n", paddr, value);
}
else
{
__sync_synchronize();
*paddr = value;
__sync_synchronize();
}
}
/* write to peripheral without the write barrier */
void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value)
{
if (debug)
{
printf("bcm2835_peri_write_nb paddr %p, value %08X\n",
paddr, value);
}
else
{
*paddr = value;
}
}
/* Set/clear only the bits in value covered by the mask
* This is not atomic - can be interrupted.
*/
void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask)
{
uint32_t v = bcm2835_peri_read(paddr);
v = (v & ~mask) | (value & mask);
bcm2835_peri_write(paddr, v);
}
/*
// Low level convenience functions
*/
/* Function select
// pin is a BCM2835 GPIO pin number NOT RPi pin number
// There are 6 control registers, each control the functions of a block
// of 10 pins.
// Each control register has 10 sets of 3 bits per GPIO pin:
//
// 000 = GPIO Pin X is an input
// 001 = GPIO Pin X is an output
// 100 = GPIO Pin X takes alternate function 0
// 101 = GPIO Pin X takes alternate function 1
// 110 = GPIO Pin X takes alternate function 2
// 111 = GPIO Pin X takes alternate function 3
// 011 = GPIO Pin X takes alternate function 4
// 010 = GPIO Pin X takes alternate function 5
//
//
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
树莓派3b上完成基于MCP2515和BCM2835的SPI转CAN,实现树莓派与外界的CAN通信。代码可以直接调用CAN_Send_Buffer(unsigned char *CAN_TX_Buf,unsigned char len, unsigned char msgID)和CAN_Receive_Buffer(unsigned char *CAN_RX_Buf)来完成标准帧发和收。接收到的数据ID在接收数组的最后一位,使用时可以直接修改初始化函数和CAN收发函数。文件内还包含有makefile,在安装好相关驱动后,可以在文件夹下测试,直接在终端make,之后sudo ./hello。
资源推荐
资源详情
资源评论
收起资源包目录
mcp.rar (9个子文件)
test.c 782B
.MCP2515.c.swo 16KB
bcm2835.h 89KB
Makefile 662B
MCP2515.h 430B
.MCP2515.c.swp 20KB
MCP2515.c 8KB
bcm2835.c 55KB
mcp2515_new.h 11KB
共 9 条
- 1
资源评论
Yellor__
- 粉丝: 47
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功