Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- *
- */
- #include <inttypes.h>
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include <avr/pgmspace.h>
- #include <stddef.h>
- #include "xmega_a4u.h"
- #define buff_size 8
- #define enable_dac_out() { DACB.CTRLA |= DAC_CH0EN_bm | DAC_CH1EN_bm | DAC_ENABLE_bm; }
- #define disable_dac_out() { DACB.CTRLA &= ~(DAC_CH0EN_bm | DAC_CH1EN_bm | DAC_ENABLE_bm); }
- #define setup_inttr_hl() { PMIC.CTRL |= PMIC_HILVLEN_bm; }
- uint8_t read_calibration_byte( uint8_t index )
- {
- uint8_t result;
- /* Load the NVM Command register to read the calibration row. */
- NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
- result = pgm_read_byte(index);
- /* Clean up NVM Command register. */
- NVM_CMD = NVM_CMD_NO_OPERATION_gc;
- return( result );
- }
- inline void dac_byte(uint8_t CH0L, uint8_t CH0H, uint8_t CH1L, uint8_t CH1H)
- {
- DACB.CH0DATAL = CH0L;
- DACB.CH0DATAH = (0x0F & CH0H);
- DACB.CH1DATAL = CH1L;
- DACB.CH1DATAH = (0x0F & CH1H);
- }
- inline void dac_word(uint16_t CH0_data, uint16_t CH1_data)
- {
- DACB.CH0DATA = (0x0FFF & CH0_data);
- DACB.CH1DATA = (0x0FFF & CH1_data);
- }
- inline void init_dac(void)
- {
- DACB.CTRLB = DAC_CHSEL_DUAL_gc;
- DACB.CTRLC = DAC_REFSEL_INT1V_gc;
- DACB.CH1DATA = 0x000;
- DACB.CH0DATA = 0x000;
- }
- //global variables
- static volatile uint8_t twi_recv_buffer[buff_size], twi_send_buffer[buff_size];
- static volatile uint8_t recv_bf_cnt, send_bf_cnt, num_bytes, count_isr;
- inline void setup_twi_slave(void)
- {
- TWIC.CTRL = TWI_SDAHOLD_50NS_gc ;
- TWIC.SLAVE.ADDR = 0x25 ;
- TWIC.SLAVE.CTRLA |= TWI_SLAVE_PIEN_bm | TWI_SLAVE_DIEN_bm | TWI_SLAVE_APIEN_bm | TWI_SLAVE_ENABLE_bm | TWI_SLAVE_INTLVL_HI_gc;
- }
- inline void slave_process_master_read(void){
- twi_send_buffer[0] = 0x00 ;
- twi_send_buffer[1] = 0x00 ;
- twi_send_buffer[2] = 0x00 ;
- twi_send_buffer[3] = 0x00 ;
- twi_send_buffer[4] = 0x00 ;
- }
- inline void slave_process_master_write(void){
- dac_byte(twi_recv_buffer[2], twi_recv_buffer[1], twi_recv_buffer[4], twi_recv_buffer[3]);
- }
- inline void twi_slave_isr_handler(void){
- // HANDLE ADDRESS MATCH
- if(TWIC.SLAVE.STATUS & TWI_SLAVE_APIF_bm){
- if(TWIC.SLAVE.STATUS & TWI_SLAVE_AP_bm){
- TWIC.SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc ;
- recv_bf_cnt = 0x00 ;
- send_bf_cnt = 0x00 ;
- }else{
- TWIC.SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc ;
- slave_process_master_write() ;
- recv_bf_cnt = 0x00 ;
- send_bf_cnt = 0x00 ;
- }
- }else{
- //HANDE DATA MATCH
- if(TWIC.SLAVE.STATUS & TWI_SLAVE_DIF_bm){
- //MASTER READ
- if(TWIC.SLAVE.STATUS & TWI_SLAVE_DIR_bm){
- if((send_bf_cnt > 0) && (TWIC.SLAVE.STATUS & TWI_SLAVE_RXACK_bm)) {
- send_bf_cnt = 0x00 ;
- TWIC.SLAVE.CTRLB = TWI_SLAVE_ACKACT_bm | TWI_SLAVE_CMD_COMPTRANS_gc;
- }else{
- if(send_bf_cnt < buff_size){
- uint8_t data = twi_send_buffer[send_bf_cnt] ;
- TWIC.SLAVE.DATA = data ;
- send_bf_cnt++ ;
- /* Send data, wait for data interrupt. */
- if(send_bf_cnt == buff_size){
- /* End transaction, reset buffer index */
- send_bf_cnt = 0x00 ;
- TWIC.SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc ;
- }else{
- TWIC.SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc ;
- }
- }else{
- /* End transaction, reset buffer index */
- TWIC.SLAVE.CTRLB = TWI_SLAVE_ACKACT_bm | TWI_SLAVE_CMD_COMPTRANS_gc;
- send_bf_cnt = 0x00 ;
- }
- }
- //MASTER WRITE
- }else{
- if(recv_bf_cnt < buff_size){
- twi_recv_buffer[recv_bf_cnt] = TWIC.SLAVE.DATA ;
- recv_bf_cnt++ ;
- if(recv_bf_cnt == buff_size){
- /* End transaction, reset buffer index */
- TWIC.SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc ;
- send_bf_cnt = 0x00 ;
- slave_process_master_write() ;
- }else{
- TWIC.SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc ;
- }
- }else{
- /* End transaction, reset buffer index */
- TWIC.SLAVE.CTRLB = TWI_SLAVE_ACKACT_bm | TWI_SLAVE_CMD_COMPTRANS_gc;
- recv_bf_cnt = 0x00 ;
- slave_process_master_write() ;
- }
- }
- }
- }
- }
- ISR(TWIC_TWIS_vect) {
- twi_slave_isr_handler();
- }
- ISR(ADCA_CH0_vect) {
- uint16_t temp = (0x00ff & ADCA.CH0RESL);
- temp |= (ADCA.CH0RESH << 8);
- twi_send_buffer[0] = (0xff & temp);
- twi_send_buffer[1] = (temp >> 8) ;
- }
- inline void setup_adc(void){
- ADCA.CTRLA = ADC_ENABLE_bm;
- ADCA.CTRLB = ADC_FREERUN_bm/* | ADC_CONMODE_bm*/;
- ADCA.PRESCALER = ADC_PRESCALER2_bm;
- ADCA.CH0.INTCTRL = ADC_CH_INTMODE_COMPLETE_gc | ADC_CH_INTLVL1_bm | ADC_CH_INTLVL0_bm;
- PORTA.DIRCLR = PIN0_bm;
- ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
- ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc/* | ADC_CH_MUXNEG_GND_MODE3_gc*/;//PB1
- ADCA.REFCTRL = ADC_REFSEL_INT1V_gc; //VCC 1V; bandgap is enabled because the DAC uses it; otherwise enable it separately
- }
- int main(void)
- {
- setup_clk_32M_int();
- init_dac();
- enable_dac_out();
- uint16_t data0=0x0000;
- uint16_t data1=0x0000;
- slave_process_master_read();
- dac_word(data0, data1);
- setup_twi_slave();
- setup_adc();
- setup_inttr_hl();
- sei();
- ADCA.CH0.CTRL |= 0b10000000; // start conversion
- while(1){
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement