Obsolete IIC calls in the RPi build?
Jeffrey Lee (213) 6048 posts |
They aren’t inaccessible. If you’re programming one of the DMA controllers then you need to give it GPU physical addresses. |
Nathanael Smith (1763) 17 posts |
Sorry to interupt – I got my code fully working: // Demo code to access Flexel Data Aquisition Module // from Raspberry Pi (first Revision) running RISC OS via BSC registers //------------- Header files #include <stdio.h> #include <stdlib.h> #include "kernel.h" #include "swis.h" //------------- Define start of BSC register addresses #define BSC_physical 0x20205000 //------------- use 0x20804000 for a second revision board //------------- Define read, write, cleansing and status values #define BSC_C_I2CEN (1 << 15) #define BSC_C_INTR (1 << 10) #define BSC_C_INTT (1 << 9) #define BSC_C_INTD (1 << 8) #define BSC_C_ST (1 << 7) #define BSC_C_CLEAR (1 << 4) #define BSC_C_CLEAR_II (1 << 5) #define BSC_C_READ 1 #define CLEAR_FIFO BSC_C_CLEAR|BSC_C_CLEAR_II #define START_READ BSC_C_I2CEN|BSC_C_ST|BSC_C_CLEAR|BSC_C_READ #define START_WRITE BSC_C_I2CEN|BSC_C_ST #define BSC_S_CLKT (1 << 9) #define BSC_S_ERR (1 << 8) #define BSC_S_RXF (1 << 7) #define BSC_S_TXE (1 << 6) #define BSC_S_RXD (1 << 5) #define BSC_S_TXD (1 << 4) #define BSC_S_RXR (1 << 3) #define BSC_S_TXW (1 << 2) #define BSC_S_DONE (1 << 1) #define BSC_S_TA 1 #define CLEAR_STATUS BSC_S_CLKT|BSC_S_ERR|BSC_S_DONE //------------- Function declarations unsigned int Memory_Map(unsigned int base); void ByteWriteI2C(unsigned short int device_addr, unsigned char data_byte); unsigned short int ByteReadI2C(unsigned short int device_addr); void wait_i2c_done(); void init(); void EmptyFIFO(); void MultiByteWriteI2C(unsigned short int device_addr, unsigned short int length); void MultiByteReadI2C(unsigned short int device_addr, unsigned short int length); //------------- Set up pointers to mapped logical address unsigned char FIFO_access[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; unsigned int BSC_logical; unsigned int volatile * BSC_C; unsigned int volatile * BSC_S; unsigned int volatile * BSC_DLEN; unsigned int volatile * BSC_A; unsigned int volatile * BSC_FIFO; void init() { printf("\ninitialising...\n"); BSC_logical = Memory_Map(BSC_physical); BSC_C = (unsigned int *) (BSC_logical+0x0); BSC_S = (unsigned int *) (BSC_logical+0x04); BSC_DLEN = (unsigned int *) (BSC_logical+0x08); BSC_A = (unsigned int *) (BSC_logical+0x0C); BSC_FIFO = (unsigned int *) (BSC_logical+0x10); *BSC_C=CLEAR_FIFO; } //------------- Map physical addresses to logical addresses unsigned int Memory_Map(unsigned int base) { printf("mapping..."); _kernel_swi_regs r; r.r[0] = (1 << 17) + 13; r.r[1] = base; r.r[2] = 1024; _kernel_swi(OS_Memory, &r, &r); return r.r[3]; } //——————— Function to empty FIFO void EmptyFIFO() { *BSC_C=CLEAR_FIFO; } //——————— Function to write one byte to I2C bus void ByteWriteI2C(unsigned short int device_addr, unsigned char data_byte) { printf("\nchanging BSC register values...\n"); *BSC_C=CLEAR_FIFO; *BSC_S = CLEAR_STATUS; *BSC_A = device_addr; *BSC_DLEN = 1; *BSC_FIFO = data_byte; printf("starting to write transaction...\n"); *BSC_C = START_WRITE; wait_i2c_done(); } //——————— Function to read one byte from I2C bus unsigned short int ByteReadI2C(unsigned short int device_addr) { printf("\nchanging BSC register values to send bus address only...\n"); *BSC_C=CLEAR_FIFO; *BSC_S = CLEAR_STATUS; *BSC_A = device_addr; *BSC_DLEN = 1; printf("starting to write transaction...\n"); *BSC_C = START_WRITE; wait_i2c_done(); printf("changing BSC register values to read...\n"); *BSC_S = CLEAR_STATUS; *BSC_A = device_addr; *BSC_DLEN = 1; printf("starting to send transaction...\n"); *BSC_C = START_READ; wait_i2c_done(); printf("reading one byte from FIFO...\n"); return *BSC_FIFO; } //——————— Function to write multiple bytes to I2C bus void MultiByteWriteI2C(unsigned short int device_addr, unsigned short int length) { unsigned short int i=0; printf("\nchanging BSC register values...\n"); *BSC_C=CLEAR_FIFO; *BSC_S = CLEAR_STATUS; *BSC_A = device_addr; *BSC_DLEN = length; while(i<length) { *BSC_FIFO=FIFO_access[i]; FIFO_access[i]=0; i++; } printf("starting to write transaction...\n"); *BSC_C = START_WRITE; wait_i2c_done(); } //——————— Function to read Multiple bytes from I2C bus void MultiByteReadI2C(unsigned short int device_addr, unsigned short int length) { unsigned short int i=0; printf("\nchanging BSC register values to send bus address only...\n"); *BSC_C = CLEAR_FIFO; *BSC_S = CLEAR_STATUS; *BSC_A = device_addr; *BSC_DLEN = 0; printf("starting to write transaction...\n"); *BSC_C = START_WRITE; wait_i2c_done(); printf("changing BSC register values to read...\n"); *BSC_S = CLEAR_STATUS; *BSC_A = device_addr; *BSC_DLEN = length; printf("starting to send transaction...\n"); *BSC_C = START_READ; wait_i2c_done(); printf("reading multiple bytes from FIFO...\n"); while(i<length) { FIFO_access[i]=*BSC_FIFO; i++; } } //------------- display I2C transaction status void dump_bsc_status() { unsigned int s = *BSC_S; printf("BSC0_S: ERR=%d RXF=%d TXE=%d RXD=%d TXD=%d RXR=%d TXW=%d DONE=%d TA=%d\n", (s & BSC_S_ERR) != 0, (s & BSC_S_RXF) != 0, (s & BSC_S_TXE) != 0, (s & BSC_S_RXD) != 0, (s & BSC_S_TXD) != 0, (s & BSC_S_RXR) != 0, (s & BSC_S_TXW) != 0, (s & BSC_S_DONE) != 0, (s & BSC_S_TA) != 0 ); } //------------- Function to wait for the I2C transaction to complete void wait_i2c_done() { printf("status before completion - "); dump_bsc_status(); printf("waiting for transaction to complete...\n"); unsigned short int timeout = 50; unsigned short int i; while((!((*BSC_S) & BSC_S_DONE)) && --timeout) { i=0; while(i<5000) { i++; } } if(timeout == 0) printf("wait_i2c_done() timeout. Something went wrong.\n"); printf("status after completion - "); dump_bsc_status(); } //------------- Here we go...! int main(int argc, char **argv) { // initialise init(); // send characters to screen ByteWriteI2C(0x48,48); //send '0' to lcd ByteWriteI2C(0x48,49); //send '1' to lcd ByteWriteI2C(0x48,50); //send '2' to lcd ByteWriteI2C(0x48,51); //send '3' to lcd ByteWriteI2C(0x48,52); //send '4' to lcd ByteWriteI2C(0x48,53); //send '5' to lcd ByteWriteI2C(0x48,54); //send '6' to lcd ByteWriteI2C(0x48,55); //send '7' to lcd ByteWriteI2C(0x48,56); //send '8' to lcd ByteWriteI2C(0x48,57); //send '9' to lcd // turn down LCD backlight FIFO_access[0]=0xFE; FIFO_access[1]=0x03; FIFO_access[2]=0x10; MultiByteWriteI2C(0x48,3); //read and display time from Real Time Clock FIFO_access[0]=0xFE; FIFO_access[1]=0x2A; MultiByteWriteI2C(0x48,2); MultiByteReadI2C(0x48,3); printf("\nTime: %d hours %d minutes %d seconds\n",FIFO_access[2],FIFO_access[1],FIFO_access[0]); return 0; } Thanks again. |