Beispiel #1
0
static rt_err_t sd_mmc_init(rt_device_t dev)
{
	pdca_channel_rx = pdca_get_handler(PDCA_CHANNEL_SPI_RX);
	pdca_channel_tx = pdca_get_handler(PDCA_CHANNEL_SPI_TX);

	return RT_EOK;
}
Beispiel #2
0
uint32_t pdca_init_channel(uint8_t pdca_ch_number,
		const pdca_channel_options_t *opt)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_disable_interrupt_transfer_complete(pdca_ch_number); 
	pdca_disable_interrupt_reload_counter_zero(pdca_ch_number);
	
	irqflags_t flags = cpu_irq_save();

	pdca_channel->mar = (uint32_t)opt->addr;
	pdca_channel->tcr = opt->size;
	pdca_channel->psr = opt->pid;
	pdca_channel->marr = (uint32_t)opt->r_addr;
	pdca_channel->tcrr = opt->r_size;
	pdca_channel->mr =
#if (AVR32_PDCA_H_VERSION >= 120)
			opt->etrig << AVR32_PDCA_ETRIG_OFFSET |
#endif
			opt->transfer_size << AVR32_PDCA_SIZE_OFFSET;
	pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
	pdca_channel->isr;
	
	cpu_irq_restore(flags);

	return PDCA_SUCCESS;
}
Beispiel #3
0
bool pdca_get_channel_status(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	return (pdca_channel->sr & AVR32_PDCA_TEN_MASK) != 0;
}
Beispiel #4
0
uint32_t pdca_get_transfer_status(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	return pdca_channel->isr;
}
Beispiel #5
0
void pdca_enable_event_trigger(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_channel->mr |= AVR32_PDCA_ETRIG_MASK;
}
Beispiel #6
0
void pdca_enable_interrupt_reload_counter_zero(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_channel->ier = AVR32_PDCA_RCZ_MASK;
}
Beispiel #7
0
void pdca_enable_interrupt_transfer_complete(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_channel->ier = AVR32_PDCA_TRC_MASK;
}
Beispiel #8
0
void pdca_set_peripheral_select(uint8_t pdca_ch_number, uint32_t pid)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_channel->psr = pid;
}
Beispiel #9
0
uint32_t pdca_get_reload_size(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	return pdca_channel->tcrr;
}
Beispiel #10
0
void pdca_enable(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	/* Enable transfer */
	pdca_channel->cr = AVR32_PDCA_TEN_MASK;
}
Beispiel #11
0
void pdca_set_transfer_size(uint8_t pdca_ch_number,
		uint32_t transfer_size)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	pdca_channel->mr = (pdca_channel->mr & ~AVR32_PDCA_SIZE_MASK) |
			transfer_size << AVR32_PDCA_SIZE_OFFSET;
}
Beispiel #12
0
int media_read(unsigned long sector, unsigned char *buffer, unsigned long sector_count) {
#if 1
#else
  unsigned long i;

  for (i=0;i<sector_count;i++) {
    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_RX,
		       &pdcaRxBuf,
		       FS_BUF_SIZE);
    
    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_TX,
		       (void *)&pdcaTxBuf,
		       FS_BUF_SIZE); //send dummy to activate the clock
    
    fsEndTransfer = false;
    
    if(sd_mmc_spi_read_open_PDCA (sector)) {

      spi_write(SD_MMC_SPI,0xFF); // dummy byte synchronizes transfer

      pdca_enable_interrupt_transfer_complete(AVR32_PDCA_CHANNEL_SPI_RX);
      pdcaRxChan =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_RX);
      pdcaTxChan =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_TX);
      pdcaRxChan->cr = AVR32_PDCA_TEN_MASK; // Enable RX PDCA transfer first
      pdcaTxChan->cr = AVR32_PDCA_TEN_MASK; // and TX PDCA transfer
      // wait for signal from ISR
      while(!fsEndTransfer) { ;; }
      // copy FIXME: could optimize away
      for(i=0; i<FS_BUF_SIZE; i++) {
	buffer[i] = pdcaRxBuf[i];
      }
    } else {
      print_dbg("\r\n error opening PDCA at sector "); 
      print_dbg_ulong(sector);
    }
    sector ++;
    buffer += FS_BUF_SIZE;
  }
  return 1;
#endif
}
Beispiel #13
0
void pdca_disable_interrupt_reload_counter_zero(uint8_t pdca_ch_number)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	irqflags_t flags = cpu_irq_save();

	pdca_channel->idr = AVR32_PDCA_RCZ_MASK;
	pdca_channel->isr;

	cpu_irq_restore(flags);
}
Beispiel #14
0
void pdca_load_channel(uint8_t pdca_ch_number, volatile void *addr,
		uint32_t size)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	irqflags_t flags = cpu_irq_save();

	pdca_channel->mar = (uint32_t)addr;
	pdca_channel->tcr = size;
	pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
	pdca_channel->isr;

	cpu_irq_restore(flags);
}
/*! \brief Initializes SD/MMC resources: GPIO, SPI and SD/MMC.
 */
static void sd_mmc_resources_init(void)
{
  // GPIO pins used for SD/MMC interface
  static const gpio_map_t SD_MMC_SPI_GPIO_MAP =
  {
    {SD_MMC_SPI_SCK_PIN,  SD_MMC_SPI_SCK_FUNCTION },  // SPI Clock.
    {SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION},  // MISO.
    {SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION},  // MOSI.
    {SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION}   // Chip Select NPCS.
  };

  // SPI options.
  spi_options_t spiOptions =
  {
    .reg          = SD_MMC_SPI_NPCS,
    .baudrate     = SD_MMC_SPI_MASTER_SPEED,  // Defined in conf_sd_mmc_spi.h.
    .bits         = SD_MMC_SPI_BITS,          // Defined in conf_sd_mmc_spi.h.
    .spck_delay   = 0,
    .trans_delay  = 0,
    .stay_act     = 1,
    .spi_mode     = 0,
    .modfdis      = 1
  };

  // Assign I/Os to SPI.
  gpio_enable_module(SD_MMC_SPI_GPIO_MAP,
                     sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0]));

  // Initialize as master.
  spi_initMaster(SD_MMC_SPI, &spiOptions);

  // Set SPI selection mode: variable_ps, pcs_decode, delay.
  spi_selectionMode(SD_MMC_SPI, 0, 0, 0);

  // Enable SPI module.
  spi_enable(SD_MMC_SPI);

  // Initialize SD/MMC driver with SPI clock (PBA).
  sd_mmc_spi_init(spiOptions, PBA_HZ);
}


/*! \brief Initialize PDCA (Peripheral DMA Controller A) resources for the SPI transfer and start a dummy transfer
 */
void local_pdca_init(void)
{
  // this PDCA channel is used for data reception from the SPI
  pdca_channel_options_t pdca_options_SPI_RX ={ // pdca channel options

    .addr = ram_buffer,
    // memory address. We take here the address of the string dummy_data. This string is located in the file dummy.h

    .size = 512,                              // transfer counter: here the size of the string
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_RX,        // select peripheral ID - data are on reception from SPI1 RX line
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // this channel is used to activate the clock of the SPI by sending a dummy variables
  pdca_channel_options_t pdca_options_SPI_TX ={ // pdca channel options

    .addr = (void *)&dummy_data,              // memory address.
                                              // We take here the address of the string dummy_data.
                                              // This string is located in the file dummy.h
    .size = 512,                              // transfer counter: here the size of the string
    .r_addr = NULL,                           // next memory address after 1st transfer complete
    .r_size = 0,                              // next transfer counter not used here
    .pid = AVR32_PDCA_CHANNEL_USED_TX,        // select peripheral ID - data are on reception from SPI1 RX line
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE  // select size of the transfer: 8,16,32 bits
  };

  // Init PDCA transmission channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_TX, &pdca_options_SPI_TX);

  // Init PDCA Reception channel
  pdca_init_channel(AVR32_PDCA_CHANNEL_SPI_RX, &pdca_options_SPI_RX);

  //! \brief Enable pdca transfer interrupt when completed
  INTC_register_interrupt(&pdca_int_handler, AVR32_PDCA_IRQ_0, AVR32_INTC_INT1);  // pdca_channel_spi1_RX = 0

}


/*! \brief Main function. Execution starts here.
 */
int main(void)
{
  int i, j;


  // Switch the main clock to the external oscillator 0
  pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

  // Initialize debug RS232 with PBA clock
  init_dbg_rs232(PBA_HZ);

  //start test
  print_dbg("\r\nInit SD/MMC Driver");
  print_dbg("\r\nInsert SD/MMC...");

  // Initialize Interrupt Controller
  INTC_init_interrupts();

  // Initialize SD/MMC driver resources: GPIO, SPI and SD/MMC.
  sd_mmc_resources_init();

  // Wait for a card to be inserted
  while (!sd_mmc_spi_mem_check());
  print_dbg("\r\nCard detected!");

  // Read Card capacity
  sd_mmc_spi_get_capacity();
  print_dbg("Capacity = ");
  print_dbg_ulong(capacity >> 20);
  print_dbg(" MBytes");

  // Enable all interrupts.
  Enable_global_interrupt();

  // Initialize PDCA controller before starting a transfer
  local_pdca_init();

  // Read the first sectors number 1, 2, 3 of the card
  for(j = 1; j <= 3; j++)
  {
    // Configure the PDCA channel: the address of memory ram_buffer to receive the data at sector address j
    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_RX,
                     &ram_buffer,
                     512);

    pdca_load_channel( AVR32_PDCA_CHANNEL_SPI_TX,
                     (void *)&dummy_data,
                     512); //send dummy to activate the clock

    end_of_transfer = false;
    // open sector number j
    if(sd_mmc_spi_read_open_PDCA (j))
    {
      print_dbg("\r\nFirst 512 Bytes of Transfer number ");
      print_dbg_ulong(j);
      print_dbg(" :\r\n");

      spi_write(SD_MMC_SPI,0xFF); // Write a first dummy data to synchronize transfer
      pdca_enable_interrupt_transfer_complete(AVR32_PDCA_CHANNEL_SPI_RX);
      pdca_channelrx =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_RX); // get the correct PDCA channel pointer
      pdca_channeltx =(volatile avr32_pdca_channel_t*) pdca_get_handler(AVR32_PDCA_CHANNEL_SPI_TX); // get the correct PDCA channel pointer
      pdca_channelrx->cr = AVR32_PDCA_TEN_MASK; // Enable RX PDCA transfer first
      pdca_channeltx->cr = AVR32_PDCA_TEN_MASK; // and TX PDCA transfer

      while(!end_of_transfer);

      // Display the first 2O bytes of the ram_buffer content
      for( i = 0; i < 20; i++)
      {
        print_dbg_char_hex( (U8)(*(ram_buffer + i)));
      }
    }
    else
    {
      print_dbg("\r\n! Unable to open memory \r\n");
    }
  }
  print_dbg("\r\nEnd of the example.\r\n");

  while (1);
}
Beispiel #16
0
/**
 ** PDCA Init.
 **/
void init_pdca(void)
{
  // PDCA channel 0/1 options
  static const pdca_channel_options_t PDCA_CH_OPTIONS =
  {
    .addr = (void *)aDataTransfered,          // memory address
    .pid = AVR32_PDCA_PID_USART2_TX,          // select peripheral - data are transmit on USART TX line.
    .size = 0,                                // transfer counter
    .r_addr = (void *)aDataTransfered,        // next memory address
    .r_size = sizeof(aDataTransfered),        // next transfer counter
    .transfer_size = PDCA_TRANSFER_SIZE_BYTE, // select size of one data packet
    .etrig = true                          // Trigger transfer on event.
  };

  Disable_global_interrupt();

  // Initialize interrupt vectors.
  INTC_init_interrupts();

  // Register the PDCA interrupt handler to the interrupt controller.
  INTC_register_interrupt(&pdca_int_handler, PDCA_CHANNEL_IRQ, AVR32_INTC_INT0);

  Enable_global_interrupt();

  // Init PDCA channel with the pdca_options.
  pdca_init_channel(PDCA_CHANNEL_USART, &PDCA_CH_OPTIONS);
  pdca_channel = pdca_get_handler(PDCA_CHANNEL_USART); // For use in the pdca interrupt handler.

  // Enable pdca transfer error interrupt & transfer complete interrupt.
  pdca_enable_interrupt_transfer_error(PDCA_CHANNEL_USART);
  pdca_enable_interrupt_transfer_complete(PDCA_CHANNEL_USART);

  // Enable the PEVC channel "PDCA CHANNEL 0/1 ONE-ITEM-TRANSFER"
  PEVC_CHANNELS_ENABLE(ppevc, 1<<PEVC_PDCA_SOT_USER);

  // Enable the PDCA.
  pdca_enable(PDCA_CHANNEL_USART);
}

/**
 ** AST Init.
 **/
void init_ast(void)
{

  avr32_ast_pir0_t pir = {
    .insel = 14 // Set a event every second
  };

  ast_calendar_t ast_calendar;
  ast_calendar.FIELD.sec  = 30;
  ast_calendar.FIELD.min  = 45;
  ast_calendar.FIELD.hour = 12;
  ast_calendar.FIELD.day  = 7;
  ast_calendar.FIELD.month= 10;
  ast_calendar.FIELD.year = 9;

  scif_osc32_opt_t opt;
  opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL;
  opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC;

  // Start OSC_32KHZ
  scif_start_osc32(&opt,true);

  // Initialize the AST
  if (!ast_init_calendar(&AVR32_AST, AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_calendar))
  {
    print_dbg("Error initializing the AST\r\n");
    while(1);
  }

  ast_set_periodic0_value(&AVR32_AST,pir);

  ast_enable_periodic0(&AVR32_AST);

  // Clear All Interrupt
  AVR32_AST.scr=0xFFFFFFFF;

  // Enable the AST
  ast_enable(&AVR32_AST);
}

/*! \brief Initializes the MCU system clocks.
*/
static void init_sys_clocks(void)
{

  /*! \name System Clock Frequencies
   */
  //! @{
  static pcl_freq_param_t pcl_freq_param =
  {
    .cpu_f        = FCPU_HZ,
    .pba_f        = FPBA_HZ,
    .osc0_f       = FOSC0,
    .osc0_startup = OSC0_STARTUP
  };
  //! @}

  // Configure system clocks.
  if (pcl_configure_clocks(&pcl_freq_param) != PASS) {
    while(1);
  }
}

/*! \brief This example show a DMA transfer to USART controlled by the AST
    periodic alarm using the PEVC.
 */
int main(void)
{
  int i;

  // Init the string with a simple recognizable pattern.
  for(i=0;i<sizeof(aDataTransfered);i++)
    aDataTransfered[i] = '0' + (i%36);

  init_sys_clocks();

  init_usart();

  gpio_clr_gpio_pin(LED0_GPIO);

  init_pevc();

  init_ast();

  init_pdca();

  while(1)
  {
    gpio_tgl_gpio_pin(LED1_GPIO);
    delay_ms(500); //Wait 500ms
  }
}