terms

advertisement
Time-Division Multiplexing (TDM) is a type of digital or (rarely) analog multiplexing in which
two or more signals or bit streams are transferred apparently simultaneously as sub-channels in
one communication channel, but physically are taking turns on the channel
pLEDS
pFlashA_PortB_Data
pBUTTONS
pFIO_FLAG_D
AUDIO_IN
iRxBuffer1[INTERNAL_ADC_L1]
AUDIO_OUT
iTxBuffer1[INTERNAL_DAC_L1]
RESET_AUDIO
*pDMA1_IRQ_STATUS = 0x0001
RESET_TIMER
*pTIMER_STATUS = 0x0001
RESET_BUTTONS *pFIO_FLAG_C = 0x0F00
LED8
0x10
LED9
0x20
REC_LED
PLAY_LED
LED9
LED8
pSDRAM
(volatile unsigned char *) 0x00000000
SDRAM_SIZE
0x08000000 SDRAM_SIZE = 32MBytes
//--------------------------------------------------------------------------//
// Init_EBIU initializes the EBIU for Flash memory and SDRAM access
//--------------------------------------------------------------------------//
void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
//SDRAM
*pEBIU_SDRRC
= 0x00000817;
*pEBIU_SDBCTL
= 0x00000013;
*pEBIU_SDGCTL
= 0x0091998d;
}
There are also several variants on these types.
All of the integer types plus the char are called the integral types. float
The EBIU interfaces with various external memory such as SDRAM, ROMs, and FLASH
memory.
FLASH memory
The FLASH memory provides the access to the LEDs. There are 2 main 'registers':
FlashA_PortB_Dir and FlashA_PortB_Data. These registers have to be defined in the user
code since it is not provided in the cdefBF533.h or defBF533.h.
// C code
#define pFlashA_PortB_Dir ((volatile unsigned char *) 0x20270007)
#define pFlashA_PortB_Data ((volatile unsigned char *) 0x20270005)
*pFlashA_PortB_Dir = 0x3f; // 6 LSBs represents the 6 LEDs. Set to 1 for
// output
*pFlashA_PortB_Data = 0x00; // Reset all LEDs to 0 (off)
Programmable Flags (PFs)
Each button is linked to a specific PF.
Button PF#
SW4
PF8
SW5
PF9
SW6
PF10
SW7
PF11
There are 4 registers that need to be configured. Each bit in the FIO_INEN register input
enables the represented PF. FIO_EDGE configures the corresponding PF pin to be edge
sensitive, FIO_POLAR sets the direction of the edge (positive/negative), and FIO_DIR sets the
direction of the PF.
// C++ code
*pFIO_INEN = 0x0F00; // Set PF8-11 (all buttons) to be input enabled
*pFIO_EDGE = 0x0F00; // Set PF8-11 to be edge sensitive
*pFIO_DIR = 0x0000;
// Set all PFs to act as inputs
*pFIO_POLAR = 0x0000; // Set PF8-11 to be positive edge triggered
X_INTERRUPT_HANDLER converts the user's code into an Interrupt Service Routine which
saves registers and executes the RTI command, but clearing the interrupt must be handled inside
the code.
IVGX are general purpose interrupt signals, where X is the interrupt number ranging from 7
(highest priority) to 15 (lowest priority). All devices that require interrupts are assigned a IVG
number upon reset (note: more than one interrupt can be assigned to a single IVG). Assignments
can be changed by writing into the proper SIC_IAR register before enabling global interrupts
The register_handler function allows the user to assign an Interrupt Service Routine to an IVG
number. Assigning an interrupt to an ISR must be done before global interrupts are enabled.
register_handler takes 2 parameters:
register_handler(ik_ivgx, ISR_NAME);
ik_ivgx is the IVG number, where x = 7 to 15. The ISR_NAME can be any name the user
chooses, but must match the name provided in the EX_INTERRUPT_HANDLER.
The EX_INTERRUPT_HANDLER is a defined macro located in 'sys/exception.h'. This macro
assumes responsibility of saving registers and executing the Return From Interrupt (RTI)
statement after the interrupt is finished.
The register_handler function assigns the EX_INTERRUPT_HANDLER's code to the signal
name. Blackfin supports 9 general purpose interrupts (IVG7-IVG15). Assignment to an
interrupt is as follows:
*pFIO_DIR = 0x0000;
// Set PF8 to act as an input
*pFIO_POLAR = 0x0000;
// Set PF8 to be positive edge triggered
*pFIO_EDGE = 0x0100;
// Set PF8 to be edge sensitive
*pFIO_INEN = 0x0100;
// Set PF8 to enable input
*pFIO_MASKA_D = 0x0100;
// Assign Flag Interrupt A to PF8
SPORT Configuration registers
Some of the available options on transmit and receive configuration registers are listed in the
table below. Both transmit and receive share the same options, but have different names (T
denoting transmit, and R denoting receive).
SPORTx_TCR1 and SPORTx_RCR1
C++
Comment
Clear bit to 0
def
Set bit to 1
TFSR
RFSR
Frame sync
required
Does not require frame sync for
every word
Requires frame sync for every
word
ITFS
IRFS
Internal frame
sync
Use external frame sync
Use internal frame sync
ITCLK
Internal clock
IRCLK
Use external clock
Use internal clock
TSPEN
Enable
RSPEN
Disable transmit or receive
Enable transmit or receive
SPORTx_TCR2 and SPORTx_RCR2
C++
def
Comment
Clear bit to 0
Set bit to 1
SLEN
32 bit serial
word length
n/a
n/a
Note that you must specify the serial word length manually if you do not want a 32 bit serial
word length. Information about how to do this, and other options can be found in Chapter 12 of
the Hardware Reference Manual.
SPORT Transmit/Receive Buffers
There are 2 buffers that you can manipulate data from: SPORTx_TX and SPORTx_RX, where
x = 0 or 1. Read access should not be allowed on the SPORTx_TX, and writes to the
SPORTx_RX should not be allowed. Either of these conditions will produce a Peripheral
Access Bus (PAB) error (more information in the hardware manual). The process of transferring
data is follows: a write to the transmit buffer causes the SPORT to write out the data onto the
external pins. The receiving end signals an interrupt whenever its associated buffer is full, which
an ISR would commit the appropriate action on the data.
Each of the transmit and receive buffers on the SPORT have a default DMA channel
assigned.
SPORT0_RX is on default DMA channel 1, while SPORT0_TX is on default DMA channel
2
Timers are "ivg11"; Buttons
programmable flags are "ivg12”
Call register_handler(ik_ivg#, YourFunction); (For example, register_handler(ik_ivg11,
TimerInterrupt)) Turn on the interrupt by writing a "1" to the appropriate bit of
SIC_IMASK (bit 16 for Timer0, bit 19 for the buttons).
For example, *pSIC_IMASK = 0x00010000; to enable timer interrupts)
To read the state of the buttons:



In your code, call InitButtons();
*pFIO_FLAG_D, bits 8 - 11, read "1" for a pressed button, "0" otherwise.
(For example, to look at the first button you can write: *pFIO_FLAG_D >> 8) & 0x01;
To turn LEDs on and Off:







Make sure that at the top of your code, you have:
// addresses for Port B in Flash A (LED data)
#define pFlashA_PortB_Dir (volatile unsigned char *)0x20270007
#define pFlashA_PortB_Data (volatile unsigned char *)0x20270005
In your code, call InitLEDs();
You can set turn LEDs on or off by writing 1 or 0 (respectively) to bits 0 - 5 of
*pFlashA_PortB_Data, in backwards bit order.
For example, *pFlashA_PortB_Data = 0x15; to turn on alternating LEDs).
C Cheat Sheet
Main Function
void main(void) {
}
Printf
#include <stdio.h>
void main(void) {
int i = 1;
unsigned u = 2;
long l = 3;
float f = 4.0;
double d = 5.0;
char c = 6;
unsigned char uc = 7;
printf("i = %d, u = %u, l = %l, f = %f, d = %lf, c = %c, c = %d, uc = %d\n",
i, u, l, f, d, c, c, uc);
printf("print a tab by \t and new line by \n");
}
Scanf
#include <stdio.h>
void main(void) {
int i;
printf("Print a prompt for i\n");
scanf("%d", &i);
}
Conditionals
if(flag) {
// put some statements here to execute if flag is true (flag != 0)
}
if(flag) {
// put some statements here to execute if flag is true (flag != 0)
} else {
// put some statements here to execute if flag is false (flag == 0)
}
switch(flag) {
case 0: // statements
break;
case 1: // statements
break;
case 2: // statements
break;
default: // statements
}
Looping
while(flag) {
// make sure there is some statement in here to change flag to become false.
}
for(i = 0; i < LAST; i++) {
// statements
}
Math Functions
#include <math.h>
void main(void) {
double th = pi/2;
double x, y;
// th is in radians
x = cos(th);
y = sin(th);
th = atan2(y, x);
}
Creating Functions
int functionname(type1 input1, ... , typeN *output1, ...);
the ;
int functionname(type1 input1, ... , typeN *output1, ...)
{
*output1 = // some function of the input variables.
*output2 = // some function of the input varialbles.
...
return(someintvalue);
}
// this is the function prototype with
In the Process_Data() function, comment out the transfer of the input channels to the output
channels and instead set all four channels to be a 440 Hz cosine wave with amplitude of
5,000,000. The code for this could look like this:
1.
2.
3.
4.
#include <math.h>
#define A 5000000000.0
#define Fs 48000.0
#define F 440.0
Sound sample you save in your buffer with samples being produced at 48KHz
In Process_data.c, create a global array variable: int audio[BUFFERLEN] to save the audio
inputs. In Talkthrough.h add the statements:
#define BUFFERLEN
5000
extern int audio[BUFFERLEN];
This declares audio as an array of audio data that can be shared among files.
References:
FIO_INEN, FIO_DIR, and FIO_POLAR need to be initialized to read the buttons.
See pages 14-23, 14-6, and 14-19 of the 533 Hardware Manual.
EBIU_AMGCTL, EBIU_AMBCTL0, and EBIU_AMBCTL1 need to be initialized to use Flash
memory, through which the LEDs are accessed. See pages 17-10 - 17-14 of the 533 Hardware
Manual.
SIC_IAR0, SIC_IAR1, SIC_IAR2, and SIC_IMASK need to be initialized to use interrupts. See
4-20 and 4-21 for the IVG to component mapping, and 4-30 - 4-34 (both of the 533 Hardware
Manual) for initializing the interrupts.
TIMER0_CONFIG, TIMER0_PERIOD, TIMER0_WIDTH, and TIMER0_ENABLE need to be
initialized to use timer 0. See 15-5 and 15-10 - 15-15 of the 533 Hardware Manual.
Download