// switch to master mode and send something, return to slave mode when done. extern void i2c_tx(u8 chip, u32 addr, u8 addr_len, u32 data_len, void* data) { while( twi_is_busy() ) {;;} status = init_master(); print_dbg("\r\nI2C init (master) : "); if(status==TWI_SUCCESS) { print_dbg("SUCCESS"); } else { print_dbg("FAIL: "); print_dbg_hex(status); } print_dbg("\r\n chip addr: "); print_dbg_hex(chip); print_dbg(", mem addr: "); print_dbg_hex(addr); print_dbg(", addr len: "); print_dbg_hex(addr_len); print_dbg(", data len: "); print_dbg_hex(data_len); print_dbg(", data (1st 4 bytes): "); print_dbg_hex(*((u32*)(data))); status = send_master(chip, addr, addr_len, data_len, data); print_dbg("\r\nI2C tx (master) : "); if(status==TWI_SUCCESS) { print_dbg("SUCCESS"); } else { print_dbg("FAIL: "); print_dbg_hex(status); } while( twi_is_busy() ) {;;} status = init_slave(); print_dbg("\r\nI2C init (slave) : "); if(status==TWI_SUCCESS) { print_dbg("SUCCESS"); } else { print_dbg("FAIL: "); print_dbg_hex(status);} }
//! //! @brief This function ensures that no underflow/underflow will never occur //! by adjusting the SSC/ABDAC frequencies. void usb_stream_resync(void) { if (!usb_stream_context->synchronized) return; if( !cpu_is_timeout(&usb_resync_timer) ) return; if( twi_is_busy() ) return; // time-out occur. Let's check frequency deviation. int nb_full_buffers = usb_stream_fifo_get_used_room(); // Frequency control if( nb_full_buffers>USB_STREAM_BUFFER_NUMBER/2 ) { // Need to increase the frequency if( nb_full_buffers >= usb_stream_resync_last_room ) { usb_stream_resync_freq_ofst += usb_stream_resync_step; usb_stream_resync_ppm_ofst += USB_STREAM_RESYNC_PPM_STEPS; usb_stream_resync_last_room = nb_full_buffers; cs2200_freq_clk_adjust((uint16_t)_32_BITS_RATIO(usb_stream_resync_freq_ofst, CS2200_FREF)); cpu_set_timeout( cpu_ms_2_cy(TIMER_USB_RESYNC_CORRECTION, FCPU_HZ), &usb_resync_timer ); } } else if (nb_full_buffers<USB_STREAM_BUFFER_NUMBER/2 ) { // Need to slow down the frequency if( nb_full_buffers <= usb_stream_resync_last_room ) { usb_stream_resync_freq_ofst -= usb_stream_resync_step; usb_stream_resync_ppm_ofst -= USB_STREAM_RESYNC_PPM_STEPS; usb_stream_resync_last_room = nb_full_buffers; cs2200_freq_clk_adjust((uint16_t)_32_BITS_RATIO(usb_stream_resync_freq_ofst, CS2200_FREF)); cpu_set_timeout( cpu_ms_2_cy(TIMER_USB_RESYNC_CORRECTION, FCPU_HZ), &usb_resync_timer ); } } }
/*! \brief Main function. Execution starts here. * * \retval 42 Fatal error. */ int main(void) { uint32_t iter=0; uint32_t cs2200_out_freq=11289600; static bool b_sweep_up=true; static uint32_t freq_step=0; // USART options. static usart_serial_options_t USART_SERIAL_OPTIONS = { .baudrate = USART_SERIAL_EXAMPLE_BAUDRATE, .charlength = USART_SERIAL_CHAR_LENGTH, .paritytype = USART_SERIAL_PARITY, .stopbits = USART_SERIAL_STOP_BIT }; // Initialize the TWI using the internal RCOSC init_twi(AVR32_PM_RCOSC_FREQUENCY); // Initialize the CS2200 and produce a default frequency. cs2200_setup(11289600, FOSC0); sysclk_init(); // Initialize the board. // The board-specific conf_board.h file contains the configuration of the board // initialization. board_init(); // Initialize the TWI init_twi(sysclk_get_pba_hz()); // Initialize Serial Interface using Stdio Library stdio_serial_init(USART_SERIAL_EXAMPLE,&USART_SERIAL_OPTIONS); // Initialize the HMatrix. init_hmatrix(); print_dbg("\r\nCS2200 Example\r\n"); // Generate a 12.288 MHz frequency out of the CS2200. print_dbg("Output 12.288 MHz\r\n"); cs2200_freq_clk_out(_32_BITS_RATIO(12288000, FOSC0)); cpu_delay_ms( 10000, sysclk_get_cpu_hz()); // Generate a 11.2896 MHz frequency out of the CS2200. print_dbg("Output 11.2896 MHz\r\n"); cs2200_freq_clk_out(_32_BITS_RATIO(cs2200_out_freq, FOSC0)); cpu_delay_ms( 10000, sysclk_get_cpu_hz()); print_dbg("Sweep from 11.2896 MHz steps of 100 PPM\r\n"); freq_step = PPM(cs2200_out_freq, 100); while(1) { uint32_t ratio; if(b_sweep_up) { if( iter<=10 ) { print_dbg("Add 100 PPM\r\n"); iter++; cs2200_out_freq += freq_step; ratio = _32_BITS_RATIO(cs2200_out_freq, FOSC0); cs2200_freq_clk_adjust((uint16_t)ratio); cpu_delay_ms( 1000, sysclk_get_cpu_hz()); while( twi_is_busy() ); } else b_sweep_up=false; } if(!b_sweep_up) { if( iter>0 ) { print_dbg("Sub 100 PPM\r\n"); iter--; cs2200_out_freq -= freq_step; ratio = _32_BITS_RATIO(cs2200_out_freq, FOSC0); cs2200_freq_clk_adjust((uint16_t)ratio); cpu_delay_ms( 1000, sysclk_get_cpu_hz()); while( twi_is_busy() ); } else b_sweep_up=true; } } }
int twi_master_write(volatile avr32_twi_t *twi, const twi_package_t *package) { // No data to send if (package->length == 0) { return TWI_INVALID_ARGUMENT; } while( twi_is_busy() ) { cpu_relax(); }; twi_nack = false; twi_busy = true; // Enable master transfer, disable slave twi->cr = AVR32_TWI_CR_MSEN_MASK #ifndef AVR32_TWI_180_H_INCLUDED | AVR32_TWI_CR_SVDIS_MASK #endif ; // set write mode, slave address and 3 internal address byte length twi->mmr = (0 << AVR32_TWI_MMR_MREAD_OFFSET) | (package->chip << AVR32_TWI_MMR_DADR_OFFSET) | ((package->addr_length << AVR32_TWI_MMR_IADRSZ_OFFSET) & AVR32_TWI_MMR_IADRSZ_MASK); // Set pointer to TWIM instance for IT twi_inst = twi; // set internal address for remote chip twi->iadr = twi_mk_addr(package->addr, package->addr_length); // get a pointer to applicative data twi_tx_data = package->buffer; // get a copy of nb bytes to write twi_tx_nb_bytes = package->length; // put the first byte in the Transmit Holding Register twi->thr = *twi_tx_data++; // mask NACK and TXRDY interrupts twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_TXRDY_MASK; // update IMR through IER twi->ier = twi_it_mask; // send data while( twi_is_busy() ) { cpu_relax(); } // Disable master transfer twi->cr = AVR32_TWI_CR_MSDIS_MASK; if( twi_nack ) return TWI_RECEIVE_NACK; return TWI_SUCCESS; }
int twi_master_read(volatile avr32_twi_t *twi, const twi_package_t *package) { // check argument if (package->length == 0) { return TWI_INVALID_ARGUMENT; } while( twi_is_busy() ) { cpu_relax(); }; twi_nack = false; twi_busy = true; // set read mode, slave address and 3 internal address byte length twi->mmr = (package->chip << AVR32_TWI_MMR_DADR_OFFSET) | ((package->addr_length << AVR32_TWI_MMR_IADRSZ_OFFSET) & AVR32_TWI_MMR_IADRSZ_MASK) | (1 << AVR32_TWI_MMR_MREAD_OFFSET); // Set pointer to TWIM instance for IT twi_inst = twi; // set internal address for remote chip twi->iadr = twi_mk_addr(package->addr, package->addr_length); // get a pointer to applicative data twi_rx_data = package->buffer; // get a copy of nb bytes to read twi_rx_nb_bytes = package->length; // Enable master transfer twi->cr = AVR32_TWI_CR_MSEN_MASK; // Send start condition twi->cr = AVR32_TWI_START_MASK; // only one byte to receive if(twi_rx_nb_bytes == 1) { // set stop bit twi->cr = AVR32_TWI_STOP_MASK; } // mask NACK and RXRDY interrupts twi_it_mask = AVR32_TWI_IER_NACK_MASK | AVR32_TWI_IER_RXRDY_MASK; // update IMR through IER twi->ier = twi_it_mask; // get data while( twi_is_busy() ) { cpu_relax(); } // Disable master transfer twi->cr = AVR32_TWI_CR_MSDIS_MASK; if( twi_nack ) return TWI_RECEIVE_NACK; return TWI_SUCCESS; }