added l0dable for workshop kit

This commit is contained in:
schneider 2011-08-12 23:46:19 +02:00
parent b76529cdb1
commit f9018b2195
5 changed files with 179 additions and 62 deletions

View File

@ -71,11 +71,12 @@
extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
extern volatile uint32_t I2CReadLength, I2CWriteLength;
extern volatile uint32_t I2CReadLength;
extern volatile uint32_t I2CWriteLength;
extern void I2C_IRQHandler( void );
extern uint32_t i2cInit( uint32_t I2cMode );
extern uint32_t i2cEngine( void );
uint32_t i2cInit( uint32_t I2cMode );
uint32_t i2cEngine( void );
#endif /* end __I2C_H */
/****************************************************************************

View File

@ -124,22 +124,26 @@ void timer32Delay(uint8_t timerNum, uint32_t delay)
}
//we do this in applications
#if 0
/**************************************************************************/
/*!
@brief Interrupt handler for 32-bit timer 0
*/
/**************************************************************************/
uint32_t timer32Callback0;
void TIMER32_0_IRQHandler(void)
{
void (*callback)(void);
/* Clear the interrupt flag */
TMR_TMR32B0IR = TMR_TMR32B0IR_MR0;
/* If you wish to perform some action after each timer 'tick' (such as
incrementing a counter variable) you can do so here */
timer32_0_counter++;
callback=(void (*)(void)) ((uint32_t)(timer32Callback0) | 1); // Enable Thumb mode!
callback();
return;
}
@ -159,7 +163,6 @@ void TIMER32_1_IRQHandler(void)
return;
}
#endif
/**************************************************************************/
/*!

View File

@ -54,6 +54,7 @@
#define TIMER32_DELAY_1MS (10) // 1mS delay = 10 ticks
#define TIMER32_DELAY_1S (10000) // 1S delay = 10000 ticks
extern uint32_t timer32Callback0;
void TIMER32_0_IRQHandler(void);
void TIMER32_1_IRQHandler(void);

View File

@ -116,3 +116,11 @@ uint8ptouint32
#o_set_shader
#o_identity
#o_transform
#I2C
I2CMasterBuffer
I2CSlaveBuffer
I2CWriteLength
I2CReadLength
i2cEngine
i2cInit
timer32Callback0

View File

@ -14,6 +14,7 @@
#include <sysinit.h>
#include <string.h>
#include <stdint.h>
#include "basic/basic.h"
#include "basic/config.h"
@ -21,88 +22,73 @@
#include "lcd/render.h"
#include "lcd/print.h"
#include "core/i2c/i2c.h"
#include "core/timer32/timer32.h"
#include "usetable.h"
// Liberated from ARM Cortex M3 CMSIS core_cm3.h
// The processor definition headers for R0ket are incomplete :-/
//I2C address: (C0-CF)
#define LK_I2C_WRITE 0xCE
#define LK_I2C_READ 0xCF
#define __I
#define __IO volatile
#define LK_I2C_CR_INPUT0 0x00
#define LK_I2C_CR_INPUT1 0x01
#define LK_I2C_CR_PSC0 0x02
#define LK_I2C_CR_PWM0 0x03
#define LK_I2C_CR_PSC1 0x04
#define LK_I2C_CR_PWM1 0x05
#define LK_I2C_CR_LS0 0x06
#define LK_I2C_CR_LS1 0x07
#define LK_I2C_CR_LS2 0x08
#define LK_I2C_CR_LS3 0x09
typedef struct {
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPU ID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control State Register */
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt / Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
__IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
__IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
__IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) Hard Fault Status Register */
__IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
__IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) Mem Manage Address Register */
__IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) Bus Fault Address Register */
__IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
__I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
__I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
__I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
__I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
__I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) ISA Feature Register */
} SCB_Type;
#define LK_I2C_LS_OFF 0x00
#define LK_I2C_LS_ON 0x01
#define LK_I2C_LS_PWM0 0x02
#define LK_I2C_LS_PWM1 0x03
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
#define LK_PIEZO RB_SPI_SS3
uint32_t VectorTableInRAM[73] __attribute__ ((aligned(1024))); // VTOR needs 1024 Byte alignment, see UM10375.PDF
void (*orig_handler)(void); // original EINT3 handler
uint8_t lkEnabled = 0;
uint8_t lk_button_mode = 0x00;
void TIMER32_0_IRQHandler(void);
uint8_t lk_ls0 = 0x00;
uint8_t lk_ls1 = 0x00;
uint8_t lk_ls2 = 0x00;
uint8_t lk_ls3 = 0x00;
// Remember: ram() must be the first function, place all other code AFTER
// because the Implementer seem not to know how to use section attributes
uint8_t lk_in0 = 0x00;
uint8_t lk_in1 = 0x00;
uint16_t lk_ticks = 0x0000;
uint8_t lk_piezo_toggle = 0x00;
static void init_lilakit(void);
static void tick_lilakit(void);
static void mainloop();
void handler(void);
void ram(void) {
uint8_t button;
uint32_t LEDs;
// populate my Vector table
memcpy(VectorTableInRAM, 0, sizeof(VectorTableInRAM));
orig_handler = (void*) VectorTableInRAM[TIMER_32_0_IRQn + 16];
VectorTableInRAM[TIMER_32_0_IRQn + 16] = (uint32_t) &TIMER32_0_IRQHandler;
// HACK: use RAM vector table to implement own IRQ handler
SCB->VTOR = (uint32_t) &VectorTableInRAM[0];
// TODO add DMB() here, as VTOR updates are NOT effective immediately
//
NVIC_EnableIRQ(TIMER_32_0_IRQn);
timer32Callback0 = handler;
/* Enable the clock for CT32B0 */
SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0);
TMR_TMR32B0MR0 = (72E6/5E3)/2;
TMR_TMR32B0MCR = (TMR_TMR32B0MCR_MR0_INT_ENABLED | TMR_TMR32B0MCR_MR0_RESET_ENABLED);
NVIC_EnableIRQ(TIMER_32_0_IRQn);
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_ENABLED;
init_lilakit();
mainloop();
NVIC_DisableIRQ(TIMER_32_0_IRQn);
NVIC_DisableIRQ(TIMER_32_0_IRQn);
TMR_TMR32B0TCR = TMR_TMR32B0TCR_COUNTERENABLE_DISABLED;
// restore VTOR
SCB->VTOR = 0;
//TODO DMB(); Cortex Manual suggests DMB after setting VTOR
// not really needed in this case
}
void TIMER32_0_IRQHandler(void)
void handler(void)
{
TMR_TMR32B0IR = TMR_TMR32B0IR_MR0;
static int time=0;
if (time==0){time=1;} else {time=0;}
gpioSetValue (RB_LED2, time);
gpioSetValue (RB_SPI_SS3, time);
gpioSetValue (LK_PIEZO, time);
}
static void mainloop(void) {
@ -126,7 +112,125 @@ static void mainloop(void) {
while(getInputRaw()==BTN_NONE){
delayms_queue_plus(10,0);
};
tick_lilakit();
return;
}
static uint32_t lkSetI2C(uint8_t cr, uint8_t value) {
I2CMasterBuffer[0] = LK_I2C_WRITE;
I2CMasterBuffer[1] = cr;
I2CMasterBuffer[2] = value;
I2CWriteLength = 3;
I2CReadLength = 0;
return i2cEngine();
}
static uint8_t lkGetI2C(uint8_t cr) {
I2CMasterBuffer[0] = LK_I2C_WRITE;
I2CMasterBuffer[1] = cr;
I2CWriteLength = 2;
I2CReadLength = 0;
i2cEngine();
I2CMasterBuffer[0] = LK_I2C_READ;
I2CMasterBuffer[1] = cr;
I2CWriteLength = 2;
I2CReadLength = 1;
i2cEngine();
return I2CSlaveBuffer[0];
}
static void lkUpdateI2C() {
lkSetI2C(LK_I2C_CR_LS0, lk_ls0);
lkSetI2C(LK_I2C_CR_LS1, lk_ls1);
lkSetI2C(LK_I2C_CR_LS2, lk_ls2);
lkSetI2C(LK_I2C_CR_LS3, lk_ls3);
}
static void lkReadI2C() {
lk_in0 = lkGetI2C(LK_I2C_CR_INPUT0);
lk_in1 = lkGetI2C(LK_I2C_CR_INPUT1);
}
static void tick_lilakit(void)
{ // every 10ms
if (lkEnabled == 0) {
return;
}
lk_ticks++;
if (lk_ticks % 10 == 0) {
lkReadI2C();
}
if ((lk_in0 & 0x02) == 0 && lk_button_mode == 0) {
lk_ticks = 0;
lk_button_mode = 1;
lk_ls1 = 0;
lk_ls1 |= LK_I2C_LS_ON << 4;
lk_ls1 |= LK_I2C_LS_ON << 6;
lkUpdateI2C();
}
if (lk_button_mode == 1 && lk_ticks > 0xFF) {
lk_button_mode = 0;
lk_ls1 = 0;
lk_ls1 |= LK_I2C_LS_PWM0 << 4;
lk_ls1 |= LK_I2C_LS_PWM1 << 6;
lkUpdateI2C();
}
}
static void init_lilakit(void) {
i2cInit(I2CMASTER); // Init I2C
lkEnabled = (lkSetI2C(LK_I2C_CR_LS0, LK_I2C_LS_OFF << 0) == I2CSTATE_ACK); // probe i2c
if (lkEnabled == 0) {
return;
}
// All LEDs off
lkSetI2C(LK_I2C_CR_LS0, LK_I2C_LS_OFF << 0);
lkSetI2C(LK_I2C_CR_LS0, LK_I2C_LS_OFF << 2);
lkSetI2C(LK_I2C_CR_LS0, LK_I2C_LS_OFF << 4);
lkSetI2C(LK_I2C_CR_LS0, LK_I2C_LS_OFF << 6);
lkSetI2C(LK_I2C_CR_LS1, LK_I2C_LS_OFF << 0);
lkSetI2C(LK_I2C_CR_LS1, LK_I2C_LS_OFF << 2);
lkSetI2C(LK_I2C_CR_LS1, LK_I2C_LS_OFF << 4);
lkSetI2C(LK_I2C_CR_LS1, LK_I2C_LS_OFF << 6);
lkSetI2C(LK_I2C_CR_LS2, LK_I2C_LS_OFF << 0);
lkSetI2C(LK_I2C_CR_LS2, LK_I2C_LS_OFF << 2);
lkSetI2C(LK_I2C_CR_LS2, LK_I2C_LS_OFF << 4);
lkSetI2C(LK_I2C_CR_LS2, LK_I2C_LS_OFF << 6);
lkSetI2C(LK_I2C_CR_LS3, LK_I2C_LS_OFF << 0);
lkSetI2C(LK_I2C_CR_LS3, LK_I2C_LS_OFF << 2);
lkSetI2C(LK_I2C_CR_LS3, LK_I2C_LS_OFF << 4);
lkSetI2C(LK_I2C_CR_LS3, LK_I2C_LS_OFF << 6);
// All PWMs off
lkSetI2C(LK_I2C_CR_PSC0, 0x00);
lkSetI2C(LK_I2C_CR_PWM0, 0x00);
lkSetI2C(LK_I2C_CR_PSC1, 0x00);
lkSetI2C(LK_I2C_CR_PWM1, 0x00);
// Prepare SS
gpioSetDir(LK_PIEZO, gpioDirection_Output);
gpioSetValue(LK_PIEZO, 1);
// Prepare blinking
lkSetI2C(LK_I2C_CR_PSC0, 0x23);
lkSetI2C(LK_I2C_CR_PWM0, 0x66);
lkSetI2C(LK_I2C_CR_PSC1, 0x75);
lkSetI2C(LK_I2C_CR_PWM1, 0x12);
// Enable both LEDs
lk_ls1 |= LK_I2C_LS_PWM0 << 4;
lk_ls1 |= LK_I2C_LS_PWM1 << 6;
lkSetI2C(LK_I2C_CR_LS1, lk_ls1);
}