示例#1
0
void bcm2835_pwm_set_clock(uint32_t divisor)
{
  // From Gerts code
  divisor &= 0xfff;
  // Stop PWM clock
  bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x01);
  bcm2835_delay(110); // Prevents clock going slow
  // Wait for the clock to be not busy
  while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    bcm2835_delay(1); 
  // set the clock divider and enable PWM clock
  bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisor << 12));
  bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x11); // Source=osc and enable
}
/* Writes (and reads) a single byte to SPI with manual chip select by user */
uint8_t bcm2835_spi_transfer_prototype(uint8_t value)
{
	volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
    volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
    uint32_t returnValue;

    /* Clear TX and RX fifos */
 //   bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
	
	/* Maybe wait for TXD */
    while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))
	{	}

    /* Write to FIFO, With barrier */
//    bcm2835_peri_write_nb(fifo, value);
		bcm2835_peri_write(fifo, value);
printf("\nbcm2835_spi_transfer_prototype: Store Write FIFO: %09X \n", *fifo);
    /* Wait for DONE to be set */
    
    while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_DONE))
	;

    /* Read any byte that was sent back by the slave while we sere sending to it */
//returnValue = bcm2835_peri_read_nb(fifo);
		returnValue = bcm2835_peri_read(fifo);
//    returnValue = bcm2835_peri_read(paddr);
    printf("\nFunction > bcm2835_spi_transfer_prototype > Return Value: %08X\n", returnValue);
		
    return returnValue;
}
示例#3
0
// Write a 1 to clear the bit in EDS
void bcm2835_gpio_set_eds(uint8_t pin)
{
    volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32;
    uint8_t shift = pin % 32;
    uint32_t value = 1 << shift;
    bcm2835_peri_write(paddr, value);
}
示例#4
0
void bcm2835_spi_begin(uint8_t cs)
{
    volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS / 4;

    DBG_MSG("IN cs=%d\n", cs);
    // Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them
    // except if we need custom Chip Select Pin
    // printf("bcm2835_spi_begin -> spi_custom_cs = %d \n",cs );

    // Do we need custom chip select control or
    // drive CE1 manually (because CE1 does not work with hardware)
    if ( cs > BCM2835_SPI_CS_NONE || cs == BCM2835_SPI_CS1 ) {
        // indicate we will use a custom GPIO port
        spi_custom_cs = cs ;

        // ok hard CE1 not working, drive it manually
        if (cs == BCM2835_SPI_CS1) {
            // Dirty Hack CE1 in now custom Chip Select GPIO 26
            // the real CE1 pin
            spi_custom_cs = RPI_GPIO_P1_26;

            bcm2835_gpio_fsel(spi_custom_cs, BCM2835_GPIO_FSEL_OUTP); // BCM2835_GPIO_FSEL_OUTP=0b001
            bcm2835_gpio_write(spi_custom_cs, HIGH);
        }

        // Mask in we use custom CS (not sure it has a real effect)
        bcm2835_peri_set_bits(paddr, BCM2835_SPI_CS_NONE, BCM2835_SPI0_CS_CS);
    }
    // Ok hardware driving of chip select
    else {
        // Just in case
        spi_custom_cs = 0 ;

        // Mask in the CS bits of CS
        bcm2835_peri_set_bits(paddr, cs, BCM2835_SPI0_CS_CS);
    }

    // Now we can drive the I/O as asked
    if (spi_custom_cs == 0) {
        // Not custom CS, so hardware driven
        bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); // CE0
        bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); // CE1
    } else {
        // so set custom CS as output, High level by default
        bcm2835_gpio_fsel(spi_custom_cs, BCM2835_GPIO_FSEL_OUTP); // Custom GPIO
        bcm2835_gpio_write(spi_custom_cs, HIGH);
    }

    // Classic pin, hardware driven
    bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); // MISO
    bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); // MOSI
    bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); // CLK

    // Set the SPI CS register to the some sensible defaults
    bcm2835_peri_write(paddr, 0); // All 0s

    // Clear TX and RX fifos
    bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
}
示例#5
0
文件: bcm2835.c 项目: ryanrolds/picar
/* Set GPIO pad behaviour for groups of GPIOs
// powerup value for all pads is
// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
*/
void bcm2835_gpio_set_pad(uint8_t group, uint32_t control)
{
  if (bcm2835_pads == MAP_FAILED)
    return;
  
    volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group;
    bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD);
}
示例#6
0
文件: bcm_del.c 项目: jimeer/i2c
// *****************************************************************************
// I2C write register using register offset
// *****************************************************************************
void bcm2835_write_i2c(uint8_t offset,uint32_t value)
{
    volatile uint32_t* paddr;
    if(offset)
        paddr = i2c0 + offset/4;
    else    
        paddr = i2c0;
    bcm2835_peri_write(paddr, value);
}
示例#7
0
// defaults to 0x5dc, should result in a 166.666 kHz I2C clock frequency.
// The divisor must be a power of 2. Odd numbers
// rounded down.
void bcm2835_i2c_setClockDivider(uint16_t divider)
{
    volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4;
    bcm2835_peri_write(paddr, divider);
    // Calculate time for transmitting one byte
    // 1000000 = micros seconds in a second
    // 9 = Clocks per byte : 8 bits + ACK
    i2c_byte_wait_us = ((float)divider / BCM2835_CORE_CLK_HZ) * 1000000 * 9;
}
示例#8
0
文件: bcm2835.c 项目: ryanrolds/picar
void bcm2835_pwm_set_clock(uint32_t divisor)
{
    if (   bcm2835_clk == MAP_FAILED
        || bcm2835_pwm == MAP_FAILED)
      return; /* bcm2835_init() failed or not root */
  
    /* From Gerts code */
    divisor &= 0xfff;
    /* Stop PWM clock */
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x01);
    bcm2835_delay(110); /* Prevents clock going slow */
    /* Wait for the clock to be not busy */
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
	bcm2835_delay(1); 
    /* set the clock divider and enable PWM clock */
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisor << 12));
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x11); /* Source=osc and enable */
}
示例#9
0
void bcm2835_i2c_setSlaveAddress(uint8_t addr)
{
	// Set I2C Device Address
#ifdef I2C_V1
	volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_A/4;
#else	
	volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_A/4;
#endif
	bcm2835_peri_write(paddr, addr);
}
示例#10
0
// set I2C clock divider by means of a baudrate number
void bcm2835_i2c_set_baudrate(uint32_t baudrate)
{
    volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4;

    uint32_t divider;

    // use 0xFFFE mask to limit a max value and round down any odd number
    divider = (BCM2835_CORE_CLK_HZ / baudrate) & 0xFFFE;

    bcm2835_peri_write(paddr, divider);
}
//void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value);
/// Call bcm2835_peri_write() with 2 parameters
/// \par            Refer
/// \par            Modify
void ope_peri_write(void)
{
volatile uint32_t* paddr;
uint32_t value;
    get_int_code();
    get_int_code();
    paddr = *((volatile uint32_t **)(buff+1));
    value = *((volatile uint32_t *)(buff+5));
    bcm2835_peri_write( paddr, value );
//    set_ope_code( OPE_PERI_WRITE );
}
示例#12
0
// initialization of GPIO and SPI
// ----------------------------------------------------------
void TFT_init_board ( void )
{
	// *************** set the pins to be an output and turn them on
	
	bcm2835_gpio_fsel( OE, BCM2835_GPIO_FSEL_OUTP );
	bcm2835_gpio_write( OE, HIGH );
	
	bcm2835_gpio_fsel( RAIO_RST, BCM2835_GPIO_FSEL_OUTP );
	bcm2835_gpio_write( RAIO_RST, HIGH );

    bcm2835_gpio_fsel( RAIO_CS, BCM2835_GPIO_FSEL_OUTP );
	bcm2835_gpio_write( RAIO_CS, HIGH );
		
	bcm2835_gpio_fsel( RAIO_RS, BCM2835_GPIO_FSEL_OUTP );
	bcm2835_gpio_write( RAIO_RS, HIGH );

    bcm2835_gpio_fsel( RAIO_WR, BCM2835_GPIO_FSEL_OUTP );
    bcm2835_gpio_write( RAIO_WR, HIGH );
	
	bcm2835_gpio_fsel( RAIO_RD, BCM2835_GPIO_FSEL_OUTP );
	bcm2835_gpio_write( RAIO_RD, HIGH );
	
	
	// *************** now the inputs
	
	bcm2835_gpio_fsel( RAIO_WAIT, BCM2835_GPIO_FSEL_INPT );
	bcm2835_gpio_set_pud( RAIO_WAIT, BCM2835_GPIO_PUD_UP);
	
	bcm2835_gpio_fsel( RAIO_INT, BCM2835_GPIO_FSEL_INPT );
	bcm2835_gpio_set_pud( RAIO_INT, BCM2835_GPIO_PUD_UP);
	
		
	// *************** set pins for SPI
	
    bcm2835_gpio_fsel(MISO, BCM2835_GPIO_FSEL_ALT0); 
    bcm2835_gpio_fsel(MOSI, BCM2835_GPIO_FSEL_ALT0); 
    bcm2835_gpio_fsel(SCLK, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_gpio_fsel(SPI_CE1, BCM2835_GPIO_FSEL_ALT0);
        
    // set the SPI CS register to the some sensible defaults
    volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/8;
    bcm2835_peri_write( paddr, 0 ); // All 0s
    
    // clear TX and RX fifos
    bcm2835_peri_write_nb( paddr, BCM2835_SPI0_CS_CLEAR );
    
	bcm2835_spi_setBitOrder( BCM2835_SPI_BIT_ORDER_MSBFIRST );      
    bcm2835_spi_setDataMode( BCM2835_SPI_MODE0 );                 
    bcm2835_spi_setClockDivider( BCM2835_SPI_CLOCK_DIVIDER_2 ); 
    bcm2835_spi_chipSelect( BCM2835_SPI_CS1 );                      
    bcm2835_spi_setChipSelectPolarity( BCM2835_SPI_CS1, LOW );    
}
示例#13
0
void bcm2835_spi_begin(void)
{
    // Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them
    bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); // CE1
    bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); // CE0
    bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); // MISO
    bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); // MOSI
    bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); // CLK
    
    // Set the SPI CS register to the some sensible defaults
    volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
    bcm2835_peri_write(paddr, 0); // All 0s
    
    // Clear TX and RX fifos
    bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
}
//!>>>>>>>>>>>>>>>>>
//!>>>>>>>>>>>>>>>>>
//! Slave Select Lines must be toggled manually with this function
extern void bcm2835_spi_write_prototype(char buf)
{
	volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
    volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
    uint32_t i;
    uint32_t tempStoreVal;

    /* This is Polled transfer as per section 10.6.1
    // BUG ALERT: what happens if we get interupted in this section, and someone else
    // accesses a different peripheral?
    // Answer: an ISR is required to issue the required memory barriers.
    */

    /* Clear TX and RX fifos */
    //bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);

    /* Set TA = 1 */
//    bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);

    {
	/* Maybe wait for TXD */
	while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))  			// Wait until it can accept data
	    ;
	
	/* Write to FIFO, WITH!!!!>>>> barrier */
	bcm2835_peri_write(fifo, buf);
 //  printf("\nFunction bcm2835_spi_write_prototype > FIFO: %02X\n", *fifo);
	
	/* Read from FIFO to prevent stalling */
	while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)				// Wait until transmission is completed
	    (void) bcm2835_peri_read_nb(fifo);
    }
    
    /* Wait for DONE to be set */
    while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_DONE))
    {
		while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)
			(void) bcm2835_peri_read(fifo);
//			printf("\nFIFO - %zu\n", bcm2835_peri_read_nb(fifo));
    };
    
   printf("\nFunction bcm2835_spi_write_prototype > Write: %02X\n", buf);
	
    /* Set TA = 0, and also set the barrier */
//   bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
	
}
示例#15
0
//  ---------------------------------------------------------------------------
//  Enables SPI function on default GPIOs.
//  ---------------------------------------------------------------------------
void bcm2835_spi_open( void )
{
    // This driver uses the default pins with GPFSEL alternative function ALT0.
    bcm2835_gpio_fsel( SPI_GPIO_CE0,  BCM2835_GPFSEL_ALT0 );
    bcm2835_gpio_fsel( SPI_GPIO_CE1,  BCM2835_GPFSEL_ALT0 );
    bcm2835_gpio_fsel( SPI_GPIO_MISO, BCM2835_GPFSEL_ALT0 );
    bcm2835_gpio_fsel( SPI_GPIO_MOSI, BCM2835_GPFSEL_ALT0 );
    bcm2835_gpio_fsel( SPI_GPIO_CLK,  BCM2835_GPFSEL_ALT0 );

    // Set SPI CS register to default values (0).
    volatile uint32_t *paddr;
    paddr = bcm2835_spi0 + BCM2835_SPI0_CS / 4;
    bcm2835_peri_write( paddr, 0 );

    // Clear FIFOs.
    bcm2835_peri_write_nb( paddr, BCM2835_SPIO_CS_CLEAR );
}
示例#16
0
文件: spi.cpp 项目: meesokim/circle
void bcm2835_spi_begin(void)
{
    volatile uint32_t* paddr;

    /* Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them */
    bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); /* CE1 */
    bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); /* CE0 */
    bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); /* MISO */
    bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); /* MOSI */
    bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); /* CLK */
    
    /* Set the SPI CS register to the some sensible defaults */
    paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
    bcm2835_peri_write(paddr, 0); /* All 0s */
    
    /* Clear TX and RX fifos */
    bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
}
示例#17
0
// Set output pin
static __inline__ void bcm2835_gpio_set(uint8_t pin)
{
  volatile uint32_t* paddr = gpio + BCM2835_GPSET0/4 + pin/32;
  uint8_t shift = pin % 32;
  bcm2835_peri_write(paddr, 1 << shift);
}
示例#18
0
// Pullup/down clock
// Clocks the value of pud into the GPIO pin
void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on)
{
    volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUDCLK0/4 + pin/32;
    uint8_t shift = pin % 32;
    bcm2835_peri_write(paddr, (on ? 1 : 0) << shift);
}
示例#19
0
// Set pullup/down
void bcm2835_gpio_pud(uint8_t pud)
{
    volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUD/4;
    bcm2835_peri_write(paddr, pud);
}
示例#20
0
文件: gpio.c 项目: Nani0119/OS-One
// Set/clear only the bits in value covered by the mask
void bcm2835_peri_set_bits(volatile u32 * paddr, u32  value, u32  mask)
{
    u32  v = bcm2835_peri_read(paddr);
    v = (v & ~mask) | (value & mask);
    bcm2835_peri_write(paddr, v);
}
示例#21
0
// Clear all output pins in the mask
void bcm2835_gpio_clr_multi(uint32_t mask)
{
    volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4;
    bcm2835_peri_write(paddr, mask);
}
示例#22
0
// Clear output pin
void bcm2835_gpio_clr(uint8_t pin)
{
    volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4 + pin/32;
    uint8_t shift = pin % 32;
    bcm2835_peri_write(paddr, 1 << shift);
}
示例#23
0
文件: bcm2835.c 项目: ryanrolds/picar
void bcm2835_gpio_set_eds_multi(uint32_t mask)
{
    volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4;
    bcm2835_peri_write(paddr, mask);
}
示例#24
0
文件: spi.cpp 项目: meesokim/circle
/* 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);
}
示例#25
0
文件: bcm2835.c 项目: ryanrolds/picar
/* Read an number of bytes from I2C sending a repeated start after writing
// the required register. Only works if your device supports this mode
*/
uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
{   
#ifdef I2C_V1
    volatile uint32_t* dlen    = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
    volatile uint32_t* fifo    = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
    volatile uint32_t* status  = bcm2835_bsc0 + BCM2835_BSC_S/4;
    volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4;
#else
    volatile uint32_t* dlen    = bcm2835_bsc1 + BCM2835_BSC_DLEN/4;
    volatile uint32_t* fifo    = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
    volatile uint32_t* status  = bcm2835_bsc1 + BCM2835_BSC_S/4;
    volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
#endif    
	uint32_t remaining = len;
    uint32_t i = 0;
    uint8_t reason = BCM2835_I2C_REASON_OK;
    
    /* Clear FIFO */
    bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
    /* Clear Status */
    bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE);
    /* Set Data Length */
    bcm2835_peri_write(dlen, 1);
    /* Enable device and start transfer */
    bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN);
    bcm2835_peri_write(fifo, regaddr[0]);
    bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
    
    /* poll for transfer has started */
    while ( !( bcm2835_peri_read(status) & BCM2835_BSC_S_TA ) )
    {
        /* Linux may cause us to miss entire transfer stage */
        if(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE)
            break;
    }
    
    /* Send a repeated start with read bit set in address */
    bcm2835_peri_write(dlen, len);
    bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST  | BCM2835_BSC_C_READ );
    
    /* Wait for write to complete and first byte back. */
    bcm2835_delayMicroseconds(i2c_byte_wait_us * 3);
    
    /* wait for transfer to complete */
    while (!(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE))
    {
        /* we must empty the FIFO as it is populated and not use any delay */
        while (remaining && bcm2835_peri_read(status) & BCM2835_BSC_S_RXD)
    	{
	    /* Read from FIFO */
	    buf[i] = bcm2835_peri_read(fifo);
	    i++;
	    remaining--;
    	}
    }
    
    /* transfer has finished - grab any remaining stuff in FIFO */
    while (remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_RXD))
    {
        /* Read from FIFO */
        buf[i] = bcm2835_peri_read(fifo);
        i++;
        remaining--;
    }
    
    /* Received a NACK */
    if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
    {
		reason = BCM2835_I2C_REASON_ERROR_NACK;
    }

    /* Received Clock Stretch Timeout */
    else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT)
    {
	reason = BCM2835_I2C_REASON_ERROR_CLKT;
    }

    /* Not all data is sent */
    else if (remaining)
    {
	reason = BCM2835_I2C_REASON_ERROR_DATA;
    }

    bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE);

    return reason;
}
示例#26
0
文件: bcm2835.c 项目: ryanrolds/picar
/* Writes an number of bytes to I2C */
uint8_t bcm2835_i2c_write(const char * buf, uint32_t len)
{
#ifdef I2C_V1
    volatile uint32_t* dlen    = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
    volatile uint32_t* fifo    = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
    volatile uint32_t* status  = bcm2835_bsc0 + BCM2835_BSC_S/4;
    volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4;
#else
    volatile uint32_t* dlen    = bcm2835_bsc1 + BCM2835_BSC_DLEN/4;
    volatile uint32_t* fifo    = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
    volatile uint32_t* status  = bcm2835_bsc1 + BCM2835_BSC_S/4;
    volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
#endif    

    uint32_t remaining = len;
    uint32_t i = 0;
    uint8_t reason = BCM2835_I2C_REASON_OK;

    /* Clear FIFO */
    bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
    /* Clear Status */
    bcm2835_peri_write(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE);
    /* Set Data Length */
    bcm2835_peri_write(dlen, len);
    /* pre populate FIFO with max buffer */
    while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) )
    {
        bcm2835_peri_write_nb(fifo, buf[i]);
        i++;
        remaining--;
    }
    
    /* Enable device and start transfer */
    bcm2835_peri_write(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
    
    /* Transfer is over when BCM2835_BSC_S_DONE */
    while(!(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE ))
    {
        while ( remaining && (bcm2835_peri_read(status) & BCM2835_BSC_S_TXD ))
    	{
	    /* Write to FIFO */
	    bcm2835_peri_write(fifo, buf[i]);
	    i++;
	    remaining--;
    	}
    }

    /* Received a NACK */
    if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
    {
	reason = BCM2835_I2C_REASON_ERROR_NACK;
    }

    /* Received Clock Stretch Timeout */
    else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT)
    {
	reason = BCM2835_I2C_REASON_ERROR_CLKT;
    }

    /* Not all data is sent */
    else if (remaining)
    {
	reason = BCM2835_I2C_REASON_ERROR_DATA;
    }

    bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE);

    return reason;
}
示例#27
0
void bcm2835_i2c_setSlaveAddress(uint8_t addr)
{
	// Set I2C Device Address
	volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_A/4;
	bcm2835_peri_write(paddr, addr);
}
示例#28
0
文件: spi.cpp 项目: meesokim/circle
/* defaults to 0, which means a divider of 65536.
// The divisor must be a power of 2. Odd numbers
// rounded down. The maximum SPI clock rate is
// of the APB clock
*/
void bcm2835_spi_setClockDivider(uint16_t divider)
{
    volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CLK/4;
    bcm2835_peri_write(paddr, divider);
}
示例#29
0
文件: bcm2835.c 项目: yihaoz/ENSC440
// Set all output pins in the mask
void bcm2835_gpio_set_multi(uint32_t mask)
{
    uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4;
    bcm2835_peri_write(paddr, mask);
}
示例#30
-1
// Set GPIO pad behaviour for groups of GPIOs
// powerup value for al pads is
// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
void bcm2835_gpio_set_pad(uint8_t group, uint32_t control)
{
    volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group*2;
    bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD);
}