int crad_create(struct _crad_info_t *p_crad_info, struct _crad_t **pp_crad) { /*! sanity check - null ptr */ if(pp_crad == 0) { return CRAD_INVALID_PARAM; } /*! allocate associated context */ crad_t *p_crad = (crad_t*)malloc(sizeof(crad_t)); /*! return allocated context */ *pp_crad = p_crad; /*! set context to default state */ memset(*pp_crad, 0, sizeof(crad_t)); /*! default state - invalid file */ p_crad->device_file = -1; // Enable PWM3 of the CPU to run at 24 MHz. { int fd = open("/psp/fmradio_xclk", O_RDONLY); if(fd > 0) { chumby_XCLK = 1; write_kernel_memory(0x80018138, 0x0c000000); // Change pin to PWM3 from GPIO. write_kernel_memory(0x80064080, 0x01800000); // Set to 24 MHz mode. write_kernel_memory(0x80064004, 0x00000008); // Enable PWM3. close(fd); } } fprintf(stderr, "Initializing...\n"); QND_Init(); fprintf(stderr, "Setting system mode...\n"); QND_SetSysMode(QND_MODE_FM|QND_MODE_RX); fprintf(stderr, "Setting country...\n"); QND_SetCountry(COUNTRY_USA); // Refresh the list of known-available channels. This can take a // while, so we do it during init. fprintf(stderr, "Refreshing station list...\n"); crad_refresh_station_list(p_crad); fprintf(stderr, "Done with refresh.\n"); return CRAD_OK; }
int gpio_set_direction(int gpio, int is_output) { uint32_t base; uint32_t offset; if (gpio < 32) base = 0xd4019000; else if (gpio < 64) base = 0xd4019004; else if (gpio < 96) base = 0xd4019008; else base = 0xd4019100; if (is_output) offset = 0x0054; else offset = 0x0060; write_kernel_memory(offset+base, 1<<(gpio&0x1f), 0, 4); return 0; }
static int select_input(int input) { if(INPUT_MIC == input) { write_kernel_memory(HW_AUDIOIN_ADCVOL_CLR, 0x00003030); } else if(INPUT_LINE1 == input) { write_kernel_memory(HW_AUDIOIN_ADCVOL_CLR, 0x00002020); write_kernel_memory(HW_AUDIOIN_ADCVOL_SET, 0x00001010); } else if(INPUT_HP == input) { write_kernel_memory(HW_AUDIOIN_ADCVOL_CLR, 0x00001010); write_kernel_memory(HW_AUDIOIN_ADCVOL_SET, 0x00002020); } else { write_kernel_memory(HW_AUDIOIN_ADCVOL_SET, 0x00003030); } return 0; }
void setup_fpga_cs1() { int i; // printf( "setting up EIM CS1 (burst interface) pads and configuring timing\n" ); // ASSUME: setup_fpga() is already called to configure gpio mux setting. // this just gets the pads set to high-speed mode // set up pads to be mapped to EIM for( i = 0; i < 16; i++ ) { write_kernel_memory( 0x20e0428 + i*4, 0xb0f1, 0, 4 ); // pad strength config'd for a 200MHz rate } // pad strength write_kernel_memory( 0x20e046c, 0xb0f1, 0, 4 ); // BCLK // write_kernel_memory( 0x20e040c, 0xb0b1, 0, 4 ); // CS0 write_kernel_memory( 0x20e0410, 0xb0f1, 0, 4 ); // CS1 write_kernel_memory( 0x20e0414, 0xb0f1, 0, 4 ); // OE write_kernel_memory( 0x20e0418, 0xb0f1, 0, 4 ); // RW write_kernel_memory( 0x20e041c, 0xb0f1, 0, 4 ); // LBA write_kernel_memory( 0x20e0468, 0xb0f1, 0, 4 ); // WAIT write_kernel_memory( 0x20e0408, 0xb0f1, 0, 4 ); // A16 write_kernel_memory( 0x20e0404, 0xb0f1, 0, 4 ); // A17 write_kernel_memory( 0x20e0400, 0xb0f1, 0, 4 ); // A18 // EIM_CS1GCR1 // 0011 0 001 1 001 0 001 00 00 1 011 1 0 1 1 1 1 1 1 // PSZ WP GBC AUS CSREC SP DSZ BCS BCD WC BL CREP CRE RFL WFL MUM SRD SWR CSEN // // PSZ = 0011 64 words page size // WP = 0 (not protected) // GBC = 001 min 1 cycles between chip select changes // AUS = 0 address shifted according to port size // CSREC = 001 min 1 cycles between CS, OE, WE signals // SP = 0 no supervisor protect (user mode access allowed) // DSZ = 001 16-bit port resides on DATA[15:0] // BCS = 00 0 clock delay for burst generation // BCD = 00 divide EIM clock by 0 for burst clock // WC = 1 write accesses are continuous burst length // BL = 011 32 word memory wrap length // CREP = 1 non-PSRAM, set to 1 // CRE = 0 CRE is disabled // RFL = 1 fixed latency reads // WFL = 1 fixed latency writes // MUM = 1 multiplexed mode enabled // SRD = 1 synch reads // SWR = 1 synch writes // CSEN = 1 chip select is enabled // 0101 0111 1111 0001 1100 0000 1011 1 0 0 1 // 0x5 7 F 1 C 0 B 9 // 0101 0001 1001 0001 1100 0000 1011 1001 // 5 1 9 1 c 0 B 9 // 0011 0001 1001 0001 0000 1011 1011 1111 write_kernel_memory( 0x21b8000 + 0x18, 0x31910BBF, 0, 4 ); // EIM_CS1GCR2 // MUX16_BYP_GRANT = 1 // ADH = 0 (0 cycles) // 0x1000 write_kernel_memory( 0x21b8004 + 0x18, 0x1000, 0, 4 ); // 9 cycles is total length of read // 2 cycles for address // +4 more cycles for first data to show up // EIM_CS1RCR1 // 00 000100 0 000 0 001 0 010 0 000 0 000 0 000 // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN // // 00 001001 0 000 0 001 0 110 0 000 0 000 0 000 // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN // // 0000 0111 0000 0011 0000 0000 0000 0000 // 0 7 0 3 0 0 0 0 // 0000 0101 0000 0000 0 000 0 000 0 000 0 000 // write_kernel_memory( 0x21b8008, 0x05000000, 0, 4 ); // 0000 0011 0000 0001 0001 0000 0000 0000 // 0000 1001 0000 0001 0110 0000 0000 0000 // write_kernel_memory( 0x21b8008 + 0x18, 0x09014000, 0, 4 ); // EIM_CS1RCR2 // 0000 0000 0 000 00 00 0 010 0 001 // APR PAT RL RBEA RBEN // APR = 0 mandatory because MUM = 1 // PAT = XXX because APR = 0 // RL = 00 because async mode // RBEA = 000 these match RCSA/RCSN from previous field // RBEN = 000 // 0000 0000 0000 0000 0000 0000 write_kernel_memory( 0x21b800c + 0x18, 0x00000200, 0, 4 ); // EIM_CS1WCR1 // 0 0 000010 000 001 000 000 010 000 000 000 // WAL WBED WWSC WADVA WADVN WBEA WBEN WEA WEN WCSA WCSN // WAL = 0 use WADVN // WBED = 0 allow BE during write // WWSC = 000100 4 write wait states // WADVA = 000 same as RADVA // WADVN = 000 this sets WE length to 1 (this value +1) // WBEA = 000 same as RBEA // WBEN = 000 same as RBEN // WEA = 010 2 cycles between beginning of access and WE assertion // WEN = 000 1 cycles to end of WE assertion // WCSA = 000 cycles to CS assertion // WCSN = 000 cycles to CS negation // 1000 0111 1110 0001 0001 0100 0101 0001 // 8 7 E 1 1 4 5 1 // 0000 0111 0000 0100 0000 1000 0000 0000 // 0 7 0 4 0 8 0 0 // 0000 0100 0000 0000 0000 0100 0000 0000 // 0 4 0 0 0 4 0 0 // 0000 0010 0000 0000 0000 0010 0000 0000 // 0000 0010 0000 0100 0000 0100 0000 0000 write_kernel_memory( 0x21b8010 + 0x18, 0x02040400, 0, 4 ); // EIM_WCR // BCM = 1 free-run BCLK // GBCD = 0 divide the burst clock by 1 // add timeout watchdog after 1024 bclk cycles write_kernel_memory( 0x21b8090, 0x701, 0, 4 ); // EIM_WIAR // ACLK_EN = 1 write_kernel_memory( 0x21b8094, 0x10, 0, 4 ); // printf( "resetting CS0 space to 64M and enabling 64M CS1 space.\n" ); write_kernel_memory( 0x20e0004, (read_kernel_memory(0x20e0004, 0, 4) & 0xFFFFFFC0) | 0x1B, 0, 4); // printf( "done.\n" ); }
void setup_fpga() { int i; // printf( "setting up EIM CS0 (register interface) pads and configuring timing\n" ); // set up pads to be mapped to EIM for( i = 0; i < 16; i++ ) { write_kernel_memory( 0x20e0114 + i*4, 0x0, 0, 4 ); // mux mapping write_kernel_memory( 0x20e0428 + i*4, 0xb0b1, 0, 4 ); // pad strength config'd for a 100MHz rate } // mux mapping write_kernel_memory( 0x20e046c - 0x314, 0x0, 0, 4 ); // BCLK write_kernel_memory( 0x20e040c - 0x314, 0x0, 0, 4 ); // CS0 write_kernel_memory( 0x20e0410 - 0x314, 0x0, 0, 4 ); // CS1 write_kernel_memory( 0x20e0414 - 0x314, 0x0, 0, 4 ); // OE write_kernel_memory( 0x20e0418 - 0x314, 0x0, 0, 4 ); // RW write_kernel_memory( 0x20e041c - 0x314, 0x0, 0, 4 ); // LBA write_kernel_memory( 0x20e0468 - 0x314, 0x0, 0, 4 ); // WAIT write_kernel_memory( 0x20e0408 - 0x314, 0x0, 0, 4 ); // A16 write_kernel_memory( 0x20e0404 - 0x314, 0x0, 0, 4 ); // A17 write_kernel_memory( 0x20e0400 - 0x314, 0x0, 0, 4 ); // A18 // pad strength write_kernel_memory( 0x20e046c, 0xb0b1, 0, 4 ); // BCLK write_kernel_memory( 0x20e040c, 0xb0b1, 0, 4 ); // CS0 write_kernel_memory( 0x20e0410, 0xb0b1, 0, 4 ); // CS1 write_kernel_memory( 0x20e0414, 0xb0b1, 0, 4 ); // OE write_kernel_memory( 0x20e0418, 0xb0b1, 0, 4 ); // RW write_kernel_memory( 0x20e041c, 0xb0b1, 0, 4 ); // LBA write_kernel_memory( 0x20e0468, 0xb0b1, 0, 4 ); // WAIT write_kernel_memory( 0x20e0408, 0xb0b1, 0, 4 ); // A16 write_kernel_memory( 0x20e0404, 0xb0b1, 0, 4 ); // A17 write_kernel_memory( 0x20e0400, 0xb0b1, 0, 4 ); // A18 write_kernel_memory( 0x020c4080, 0xcf3, 0, 4 ); // ungate eim slow clocks // rework timing for sync use // 0011 0 001 1 001 0 001 00 00 1 011 1 0 1 1 1 1 1 1 // PSZ WP GBC AUS CSREC SP DSZ BCS BCD WC BL CREP CRE RFL WFL MUM SRD SWR CSEN // // PSZ = 0011 64 words page size // WP = 0 (not protected) // GBC = 001 min 1 cycles between chip select changes // AUS = 0 address shifted according to port size // CSREC = 001 min 1 cycles between CS, OE, WE signals // SP = 0 no supervisor protect (user mode access allowed) // DSZ = 001 16-bit port resides on DATA[15:0] // BCS = 00 0 clock delay for burst generation // BCD = 00 divide EIM clock by 0 for burst clock // WC = 1 write accesses are continuous burst length // BL = 011 32 word memory wrap length // CREP = 1 non-PSRAM, set to 1 // CRE = 0 CRE is disabled // RFL = 1 fixed latency reads // WFL = 1 fixed latency writes // MUM = 1 multiplexed mode enabled // SRD = 1 synch reads // SWR = 1 synch writes // CSEN = 1 chip select is enabled // write_kernel_memory( 0x21b8000, 0x5191C0B9, 0, 4 ); write_kernel_memory( 0x21b8000, 0x31910BBF, 0, 4 ); // EIM_CS0GCR2 // MUX16_BYP_GRANT = 1 // ADH = 1 (1 cycles) // 0x1001 write_kernel_memory( 0x21b8004, 0x1000, 0, 4 ); // EIM_CS0RCR1 // 00 000101 0 000 0 000 0 000 0 000 0 000 0 000 // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN // RWSC 000101 5 cycles for reads to happen // // 0000 0111 0000 0011 0000 0000 0000 0000 // 0 7 0 3 0 0 0 0 // 0000 0101 0000 0000 0 000 0 000 0 000 0 000 // write_kernel_memory( 0x21b8008, 0x05000000, 0, 4 ); // write_kernel_memory( 0x21b8008, 0x0A024000, 0, 4 ); write_kernel_memory( 0x21b8008, 0x09014000, 0, 4 ); // EIM_CS0RCR2 // 0000 0000 0 000 00 00 0 010 0 001 // APR PAT RL RBEA RBEN // APR = 0 mandatory because MUM = 1 // PAT = XXX because APR = 0 // RL = 00 because async mode // RBEA = 000 these match RCSA/RCSN from previous field // RBEN = 000 // 0000 0000 0000 0000 0000 0000 write_kernel_memory( 0x21b800c, 0x00000000, 0, 4 ); // EIM_CS0WCR1 // 0 0 000100 000 000 000 000 010 000 000 000 // WAL WBED WWSC WADVA WADVN WBEA WBEN WEA WEN WCSA WCSN // WAL = 0 use WADVN // WBED = 0 allow BE during write // WWSC = 000100 4 write wait states // WADVA = 000 same as RADVA // WADVN = 000 this sets WE length to 1 (this value +1) // WBEA = 000 same as RBEA // WBEN = 000 same as RBEN // WEA = 010 2 cycles between beginning of access and WE assertion // WEN = 000 1 cycles to end of WE assertion // WCSA = 000 cycles to CS assertion // WCSN = 000 cycles to CS negation // 1000 0111 1110 0001 0001 0100 0101 0001 // 8 7 E 1 1 4 5 1 // 0000 0111 0000 0100 0000 1000 0000 0000 // 0 7 0 4 0 8 0 0 // 0000 0100 0000 0000 0000 0100 0000 0000 // 0 4 0 0 0 4 0 0 write_kernel_memory( 0x21b8010, 0x09080800, 0, 4 ); // write_kernel_memory( 0x21b8010, 0x02040400, 0, 4 ); // EIM_WCR // BCM = 1 free-run BCLK // GBCD = 0 don't divide the burst clock write_kernel_memory( 0x21b8090, 0x701, 0, 4 ); // EIM_WIAR // ACLK_EN = 1 write_kernel_memory( 0x21b8094, 0x10, 0, 4 ); // printf( "done.\n" ); }