git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@71 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2007-10-31 15:52:26 +00:00
parent 61319fc705
commit 2bca32f80b
6 changed files with 71 additions and 125 deletions

View File

@ -118,7 +118,6 @@ void hwinit(void) {
SetVICVector(T0IrqHandler, 0, SOURCE_Timer0);
SetVICVector(UART0IrqHandler, 1, SOURCE_UART0);
SetVICVector(UART1IrqHandler, 2, SOURCE_UART1);
SetVICVector(SSPIrqHandler, 3, SOURCE_SPI1);
/*
* System Timer initialization, 1ms intervals.

View File

@ -155,16 +155,6 @@ UART1IrqHandler:
bl UART1Irq
b IrqCommon
.globl SSPIrqHandler
SSPIrqHandler:
sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr}
mrs r0, SPSR // Workaround for ARM7TDMI+VIC
tst r0, #I_BIT // spurious interrupts.
ldmnefd sp!, {r0-r3, r12, pc}^
bl SSPIrq
b IrqCommon
/*
* Common exit point for all IRQ routines, it performs the rescheduling if
* required.

View File

@ -21,6 +21,7 @@
#include "lpc214x.h"
#include "lpc214x_serial.h"
#include "lpc214x_ssp.h"
#include "buzzer.h"
#include "evtimer.h"
@ -55,9 +56,9 @@ static t_msg Thread2(void *arg) {
}
static void TimerHandler(t_eventid id) {
static BYTE8 sspbuf[16];
t_msg TestThread(void *p);
if (!(IO0PIN & 0x00018000)) { // Both buttons
TestThread(&COM1);
PlaySound(500, 100);
@ -65,8 +66,10 @@ static void TimerHandler(t_eventid id) {
else {
if (!(IO0PIN & 0x00008000)) // Button 1
PlaySound(1000, 100);
if (!(IO0PIN & 0x00010000)) // Button 2
chFDDWrite(&COM1, (BYTE8 *)"Hello World!\r\n", 14);
if (!(IO0PIN & 0x00010000)) { // Button 2
sspRW(sspbuf, (BYTE8 *)"Hello World!\r\n", 14);
chFDDWrite(&COM1, sspbuf, 14);
}
}
}

View File

@ -399,18 +399,18 @@ typedef struct {
#define IMSC_RX 4
#define IMSC_TX 8
#define RIS_ROR 1
#define RIS_RT 2
#define RIS_RX 4
#define RIS_TX 8
#define RIS_ROR 1
#define RIS_RT 2
#define RIS_RX 4
#define RIS_TX 8
#define MIS_ROR 1
#define MIS_RT 2
#define MIS_RX 4
#define MIS_TX 8
#define MIS_ROR 1
#define MIS_RT 2
#define MIS_RX 4
#define MIS_TX 8
#define ICR_ROR 1
#define ICR_RT 2
#define ICR_ROR 1
#define ICR_RT 2
/*
* Timers/Counters.

View File

@ -22,78 +22,22 @@
#include "lpc214x.h"
#include "lpc214x_ssp.h"
static BYTE8 *ip, *op;
static int icnt, ocnt;
static t_sspnotify callback;
static void *cbpar;
#ifdef SSP_USE_MUTEX
static Semaphore me;
#endif
void SSPIrq(void) {
SSP *ssp = SSPBase;
BYTE8 b;
void sspAcquireBus(void) {
while (ssp->SSP_MIS & (MIS_ROR | MIS_RT | MIS_RX | MIS_TX)) {
if (ssp->SSP_MIS & MIS_ROR)
chSysHalt();
if (ssp->SSP_MIS & (MIS_RX | MIS_RT)) {
ssp->SSP_ICR = ICR_RT;
while (ssp->SSP_SR & SR_RNE) {
b = ssp->SSP_DR;
if (ip)
*ip++ = b;
icnt--;
}
if (icnt <= 0) { /* It should never become less than zero */
t_sspnotify fn = callback;
callback = NULL;
ssp->SSP_IMSC = 0;
VICVectAddr = 0;
fn(cbpar);
return;
}
continue;
}
/* It is MIS_TX, no need to test it again. */
while (ocnt && (ssp->SSP_SR & SR_TNF)) {
if (op)
ssp->SSP_DR = *op++;
else
ssp->SSP_DR = 0xFF;
ocnt--;
}
if (!ocnt)
ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
}
VICVectAddr = 0;
#ifdef SSP_USE_MUTEX
chSemWait(&me);
#endif
}
/*
* Starts an asynchronous SSP transfer.
* @param in pointer to the incoming data buffer, if this parameter is set to
* \p NULL then the incoming data is discarded.
* @param out pointer to the outgoing data buffer, if this parameter is set to
* \p NULL then 0xFF bytes will be output.
* @param n the number of bytes to be transferred
* @param fn callback function invoked when the operation is done
* @param par parameter to be passed to the callback function
* @return \p SSP_OK if the trasfer was started else \p SSP_RUNNING if a
* an operation was already started
*/
t_msg sspRWI(BYTE8 *in, BYTE8 *out, t_size n, t_sspnotify fn, void *par) {
void sspReleaseBus(void) {
if (callback)
return SSP_RUNNING;
callback = fn, cbpar = par, ip = in, op = out, icnt = ocnt = n;
SSPIMSC = IMSC_ROR | IMSC_RT | IMSC_RX | IMSC_TX;
return SSP_OK;
}
static void done(void *tp) {
chThdResumeI(tp);
#ifdef SSP_USE_MUTEX
chSemSignal(&me);
#endif
}
/*
@ -103,38 +47,45 @@ static void done(void *tp) {
* @param out pointer to the outgoing data buffer, if this parameter is set to
* \p NULL then 0xFF bytes will be output.
* @param n the number of bytes to be transferred
* @return \p SSP_OK if the trasfer was performed else \p SSP_RUNNING if a
* an operation was already started
* @note The transfer is performed in a software loop and is not interrupt
* driven for performance reasons, this function should be invoked
* by a low priority thread in order to "play nice" with the
* rest of the system. This kind of peripheral would really need a
* dedicated DMA channel.
*/
t_msg sspRW(BYTE8 *in, BYTE8 *out, t_size n) {
void sspRW(BYTE8 *in, BYTE8 *out, t_size n) {
int icnt, ocnt;
chSysLock();
SSP *ssp = SSPBase;
icnt = ocnt = n;
while (icnt) {
t_msg sts = sspRWI(in, out, n, done, chThdSelf());
if (sts == SSP_OK)
chSchGoSleepS(PRSUSPENDED);
if (ssp->SSP_SR & SR_RNE) {
if (in)
*in++ = ssp->SSP_DR;
else
ssp->SSP_DR;
icnt--;
continue; /* Priority over transmission. */
}
chSysUnlock();
return sts;
if (ocnt && (ssp->SSP_SR & SR_TNF)) {
if (out)
ssp->SSP_DR = *out++;
else
ssp->SSP_DR = 0xFF;
ocnt--;
}
}
}
/*
* Checks if a SSP operation is running.
* @return \p TRUE if an asynchronous operation is already running.
* SSP setup.
*/
BOOL sspIsRunningI(void) {
return callback != NULL;
}
/*
* SSP setup, must be invoked with interrupts disabled.
* Do not invoke while an operation is in progress.
*/
void SetSSPI(int cpsr, int cr0, int cr1) {
void SetSSP(int cpsr, int cr0, int cr1) {
SSP *ssp = SSPBase;
ssp->SSP_CR1 = cr1 & ~CR1_SSE;
ssp->SSP_CR1 = 0;
ssp->SSP_CR0 = cr0;
ssp->SSP_CPSR = cpsr;
ssp->SSP_CR1 = cr1 | CR1_SSE;
@ -148,8 +99,10 @@ void InitSSP(void) {
/* Enables the SPI1 clock */
PCONP = (PCONP & PCALL) | PCSPI1;
/* Clock = PCLK / 2 */
SetSSPI(2, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), 0);
/* Clock = PCLK / 2 (fastest). */
SetSSP(2, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), CR1_LBM);
VICIntEnable = INTMASK(SOURCE_SPI1);
#ifdef SSP_USE_MUTEX
chSemInit(&me, 1);
#endif
}

View File

@ -20,16 +20,17 @@
#ifndef _LPC214x_SSP_H_
#define _LPC214x_SSP_H_
#define SSP_OK RDY_OK
#define SSP_RUNNING -3
typedef void (*t_sspnotify)(void *par);
/*
* Configuration parameter, if defined this macro enforces mutual exclusion
* when invoking \p sspAcquireBus() and \p sspReleaseBus().
*/
#define SSP_USE_MUTEX
void InitSSP(void);
void SetSSPI(int cpsr, int cr0, int cr1);
void SSPIrqHandler(void);
void SetSSP(int cpsr, int cr0, int cr1);
t_msg sspRWI(BYTE8 *in, BYTE8 *out, t_size n, t_sspnotify fn, void *par);
BOOL sspIsRunningI(void);
void sspAcquireBus(void);
void sspReleaseBus(void);
void sspRW(BYTE8 *in, BYTE8 *out, t_size n);
#endif /* _LPC214x_SSP_H_*/