Fix IRQ priority issue to give working USB; and some cleanup.
parent
fb42ec17bc
commit
afe12bca23
|
@ -18,6 +18,7 @@ SRC_C = \
|
||||||
lcd.c \
|
lcd.c \
|
||||||
flash.c \
|
flash.c \
|
||||||
storage.c \
|
storage.c \
|
||||||
|
mma.c \
|
||||||
string0.c \
|
string0.c \
|
||||||
malloc0.c \
|
malloc0.c \
|
||||||
systick.c \
|
systick.c \
|
||||||
|
@ -29,10 +30,10 @@ SRC_S = \
|
||||||
startup_stm32f40xx.s \
|
startup_stm32f40xx.s \
|
||||||
|
|
||||||
PY_O = \
|
PY_O = \
|
||||||
# nlrthumb.o \
|
nlrthumb.o \
|
||||||
malloc.o \
|
malloc.o \
|
||||||
qstr.o \
|
qstr.o \
|
||||||
# misc.o \
|
misc.o \
|
||||||
lexer.o \
|
lexer.o \
|
||||||
parse.o \
|
parse.o \
|
||||||
scope.o \
|
scope.o \
|
||||||
|
|
|
@ -106,8 +106,8 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
|
||||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
||||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||||
|
|
||||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG1_FS);
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG_FS);
|
||||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG1_FS);
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG_FS);
|
||||||
|
|
||||||
/* Configure VBUS Pin (or disable VBUS_SENSING_ENABLED) */
|
/* Configure VBUS Pin (or disable VBUS_SENSING_ENABLED) */
|
||||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
|
||||||
|
@ -123,16 +123,16 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief USB_OTG_BSP_EnableInterrupt
|
* @brief USB_OTG_BSP_EnableInterrupt
|
||||||
* Enabele USB Global interrupt
|
* Enable USB Global interrupt
|
||||||
* @param None
|
* @param None
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) {
|
void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) {
|
||||||
|
// this assumes we use NVIC_PriorityGroup_4
|
||||||
NVIC_InitTypeDef NVIC_InitStructure;
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
|
|
||||||
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
|
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
|
||||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8;
|
||||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
NVIC_Init(&NVIC_InitStructure);
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_msc_mem.h"
|
#include "usbd_msc_mem.h"
|
||||||
#include "usb_conf.h"
|
#include "usb_conf.h"
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "storage.h"
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
|
@ -198,9 +201,9 @@ int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_si
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
*block_size = 512;
|
*block_size = storage_get_block_size();
|
||||||
//*block_num = SDCardInfo.CardCapacity / 512;
|
//*block_num = SDCardInfo.CardCapacity / 512;
|
||||||
*block_num = 256 + 128;
|
*block_num = storage_get_block_count();
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
@ -305,7 +308,7 @@ int8_t STORAGE_Write (uint8_t lun,
|
||||||
while (SD_GetStatus() != SD_TRANSFER_OK);
|
while (SD_GetStatus() != SD_TRANSFER_OK);
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
disk_write(0, buf, blk_addr, blk_len);
|
//disk_write(0, buf, blk_addr, blk_len);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ USBD_Usr_cb_TypeDef USR_cb = {
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void USBD_USR_Init() {
|
void USBD_USR_Init() {
|
||||||
printf("USB OTG FS\n");
|
//printf("USB OTG FS\n");
|
||||||
printf("USB device start\n");
|
//printf("USB device start\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +57,7 @@ void USBD_USR_Init() {
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void USBD_USR_DeviceReset(uint8_t speed) {
|
void USBD_USR_DeviceReset(uint8_t speed) {
|
||||||
printf("USB reset %d\n", speed);
|
//printf("USB reset %d\n", speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,7 +67,7 @@ void USBD_USR_DeviceReset(uint8_t speed) {
|
||||||
* @retval Staus
|
* @retval Staus
|
||||||
*/
|
*/
|
||||||
void USBD_USR_DeviceConfigured() {
|
void USBD_USR_DeviceConfigured() {
|
||||||
printf("USB dev config\n");
|
//printf("USB dev config\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,7 +77,7 @@ void USBD_USR_DeviceConfigured() {
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void USBD_USR_DeviceSuspended() {
|
void USBD_USR_DeviceSuspended() {
|
||||||
printf("USB dev suspend\n");
|
//printf("USB dev suspend\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +87,7 @@ void USBD_USR_DeviceSuspended() {
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void USBD_USR_DeviceResumed() {
|
void USBD_USR_DeviceResumed() {
|
||||||
printf("USB dev resume\n");
|
//printf("USB dev resume\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void USBD_USR_DeviceResumed() {
|
||||||
* @retval Staus
|
* @retval Staus
|
||||||
*/
|
*/
|
||||||
void USBD_USR_DeviceConnected() {
|
void USBD_USR_DeviceConnected() {
|
||||||
printf("USB dev connect\n");
|
//printf("USB dev connect\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ void USBD_USR_DeviceConnected() {
|
||||||
* @retval Staus
|
* @retval Staus
|
||||||
*/
|
*/
|
||||||
void USBD_USR_DeviceDisconnected() {
|
void USBD_USR_DeviceDisconnected() {
|
||||||
printf("USB dev disconn\n");
|
//printf("USB dev disconn\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
161
stm/main.c
161
stm/main.c
|
@ -9,6 +9,7 @@
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
#include "mma.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
|
|
||||||
static void impl02_c_version() {
|
static void impl02_c_version() {
|
||||||
|
@ -26,137 +27,6 @@ static void impl02_c_version() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_bits(__IO uint32_t *addr, uint32_t shift, uint32_t mask, uint32_t value) {
|
|
||||||
uint32_t x = *addr;
|
|
||||||
x &= ~(mask << shift);
|
|
||||||
x |= (value << shift);
|
|
||||||
*addr = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gpio_init() {
|
|
||||||
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOAEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void gpio_pin_af(GPIO_TypeDef *gpio, uint32_t pin, uint32_t af) {
|
|
||||||
// set the AF bits for the given pin
|
|
||||||
// pins 0-7 use low word of AFR, pins 8-15 use high word
|
|
||||||
set_bits(&gpio->AFR[pin >> 3], 4 * (pin & 0x07), 0xf, af);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void mma_init() {
|
|
||||||
// XXX
|
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1
|
|
||||||
//gpio_pin_init(GPIOB, 6 /* B6 is SCL */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
|
|
||||||
//gpio_pin_init(GPIOB, 7 /* B7 is SDA */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
|
|
||||||
//gpio_pin_af(GPIOB, 6, 4 /* AF 4 for I2C1 */);
|
|
||||||
//gpio_pin_af(GPIOB, 7, 4 /* AF 4 for I2C1 */);
|
|
||||||
|
|
||||||
// get clock speeds
|
|
||||||
RCC_ClocksTypeDef rcc_clocks;
|
|
||||||
RCC_GetClocksFreq(&rcc_clocks);
|
|
||||||
|
|
||||||
// disable the I2C peripheral before we configure it
|
|
||||||
I2C1->CR1 &= ~I2C_CR1_PE;
|
|
||||||
|
|
||||||
// program peripheral input clock
|
|
||||||
I2C1->CR2 = 4; // no interrupts; 4 MHz (hopefully!) (could go up to 42MHz)
|
|
||||||
|
|
||||||
// configure clock control reg
|
|
||||||
uint32_t freq = rcc_clocks.PCLK1_Frequency / (100000 << 1); // want 100kHz, this is the formula for freq
|
|
||||||
I2C1->CCR = freq; // standard mode (speed), freq calculated as above
|
|
||||||
|
|
||||||
// configure rise time reg
|
|
||||||
I2C1->TRISE = (rcc_clocks.PCLK1_Frequency / 1000000) + 1; // formula for trise, gives maximum rise time
|
|
||||||
|
|
||||||
// enable the I2C peripheral
|
|
||||||
I2C1->CR1 |= I2C_CR1_PE;
|
|
||||||
|
|
||||||
// set START bit in CR1 to generate a start cond!
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t i2c_get_sr() {
|
|
||||||
// must read SR1 first, then SR2, as the read can clear some flags
|
|
||||||
uint32_t sr1 = I2C1->SR1;
|
|
||||||
uint32_t sr2 = I2C1->SR2;
|
|
||||||
return (sr2 << 16) | sr1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mma_restart(uint8_t addr, int write) {
|
|
||||||
// send start condition
|
|
||||||
I2C1->CR1 |= I2C_CR1_START;
|
|
||||||
|
|
||||||
// wait for BUSY, MSL and SB --> Slave has acknowledged start condition
|
|
||||||
while ((i2c_get_sr() & 0x00030001) != 0x00030001) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write) {
|
|
||||||
// send address and write bit
|
|
||||||
I2C1->DR = (addr << 1) | 0;
|
|
||||||
// wait for BUSY, MSL, ADDR, TXE and TRA
|
|
||||||
while ((i2c_get_sr() & 0x00070082) != 0x00070082) {
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// send address and read bit
|
|
||||||
I2C1->DR = (addr << 1) | 1;
|
|
||||||
// wait for BUSY, MSL and ADDR flags
|
|
||||||
while ((i2c_get_sr() & 0x00030002) != 0x00030002) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mma_start(uint8_t addr, int write) {
|
|
||||||
// wait until I2C is not busy
|
|
||||||
while (I2C1->SR2 & I2C_SR2_BUSY) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// do rest of start
|
|
||||||
mma_restart(addr, write);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mma_send_byte(uint8_t data) {
|
|
||||||
// send byte
|
|
||||||
I2C1->DR = data;
|
|
||||||
// wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted)
|
|
||||||
int timeout = 1000000;
|
|
||||||
while ((i2c_get_sr() & 0x00070084) != 0x00070084) {
|
|
||||||
if (timeout-- <= 0) {
|
|
||||||
printf("mma_send_byte timed out!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t mma_read_ack() {
|
|
||||||
// enable ACK of received byte
|
|
||||||
I2C1->CR1 |= I2C_CR1_ACK;
|
|
||||||
// wait for BUSY, MSL and RXNE (byte received)
|
|
||||||
while ((i2c_get_sr() & 0x00030040) != 0x00030040) {
|
|
||||||
}
|
|
||||||
// read and return data
|
|
||||||
uint8_t data = I2C1->DR;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t mma_read_nack() {
|
|
||||||
// disable ACK of received byte (to indicate end of receiving)
|
|
||||||
I2C1->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
|
|
||||||
// last byte should apparently also generate a stop condition
|
|
||||||
I2C1->CR1 |= I2C_CR1_STOP;
|
|
||||||
// wait for BUSY, MSL and RXNE (byte received)
|
|
||||||
while ((i2c_get_sr() & 0x00030040) != 0x00030040) {
|
|
||||||
}
|
|
||||||
// read and return data
|
|
||||||
uint8_t data = I2C1->DR;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mma_stop() {
|
|
||||||
// send stop condition
|
|
||||||
I2C1->CR1 |= I2C_CR1_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PYB_USRSW_PORT (GPIOA)
|
#define PYB_USRSW_PORT (GPIOA)
|
||||||
#define PYB_USRSW_PIN (GPIO_Pin_13)
|
#define PYB_USRSW_PIN (GPIO_Pin_13)
|
||||||
|
|
||||||
|
@ -200,7 +70,6 @@ void __fatal_error(const char *msg) {
|
||||||
#include "compile.h"
|
#include "compile.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
py_obj_t pyb_delay(py_obj_t count) {
|
py_obj_t pyb_delay(py_obj_t count) {
|
||||||
sys_tick_delay_ms(rt_get_int(count));
|
sys_tick_delay_ms(rt_get_int(count));
|
||||||
return py_const_none;
|
return py_const_none;
|
||||||
|
@ -218,14 +87,13 @@ py_obj_t pyb_sw() {
|
||||||
return py_const_false;
|
return py_const_false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ff.h"
|
#include "ff.h"
|
||||||
FATFS fatfs0;
|
FATFS fatfs0;
|
||||||
|
|
||||||
|
#include "nlr.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include "nlr.h"
|
|
||||||
void g(uint i) {
|
void g(uint i) {
|
||||||
printf("g:%d\n", i);
|
printf("g:%d\n", i);
|
||||||
if (i & 1) {
|
if (i & 1) {
|
||||||
|
@ -262,7 +130,7 @@ void fatality() {
|
||||||
led_state(PYB_LED_G2, 1);
|
led_state(PYB_LED_G2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *fresh_boot_py =
|
static const char fresh_boot_py[] =
|
||||||
"# boot.py -- run on boot-up\n"
|
"# boot.py -- run on boot-up\n"
|
||||||
"# can run arbitrary Python, but best to keep it minimal\n"
|
"# can run arbitrary Python, but best to keep it minimal\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -316,9 +184,14 @@ static void board_info() {
|
||||||
int main() {
|
int main() {
|
||||||
// TODO disable JTAG
|
// TODO disable JTAG
|
||||||
|
|
||||||
|
// set interrupt priority config to use all 4 bits for pre-empting
|
||||||
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
|
||||||
|
|
||||||
|
// enable the CCM RAM and the GPIO's
|
||||||
|
RCC->AHB1ENR |= RCC_AHB1ENR_CCMDATARAMEN | RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
|
||||||
|
|
||||||
// basic sub-system init
|
// basic sub-system init
|
||||||
sys_tick_init();
|
sys_tick_init();
|
||||||
gpio_init();
|
|
||||||
led_init();
|
led_init();
|
||||||
|
|
||||||
// turn on LED to indicate bootup
|
// turn on LED to indicate bootup
|
||||||
|
@ -330,8 +203,8 @@ int main() {
|
||||||
storage_init();
|
storage_init();
|
||||||
|
|
||||||
// Python init
|
// Python init
|
||||||
//qstr_init();
|
qstr_init();
|
||||||
//rt_init();
|
rt_init();
|
||||||
|
|
||||||
// print a message
|
// print a message
|
||||||
printf(" micro py board\n");
|
printf(" micro py board\n");
|
||||||
|
@ -356,8 +229,8 @@ int main() {
|
||||||
__fatal_error("could not create LFS");
|
__fatal_error("could not create LFS");
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep LED on for at least 100ms
|
// keep LED on for at least 200ms
|
||||||
sys_tick_wait_at_least(stc, 100);
|
sys_tick_wait_at_least(stc, 200);
|
||||||
led_state(PYB_LED_R2, 0);
|
led_state(PYB_LED_R2, 0);
|
||||||
} else {
|
} else {
|
||||||
__fatal_error("could not access LFS");
|
__fatal_error("could not access LFS");
|
||||||
|
@ -390,8 +263,8 @@ int main() {
|
||||||
// TODO check we could write n bytes
|
// TODO check we could write n bytes
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
// keep LED on for at least 100ms
|
// keep LED on for at least 200ms
|
||||||
sys_tick_wait_at_least(stc, 100);
|
sys_tick_wait_at_least(stc, 200);
|
||||||
led_state(PYB_LED_R2, 0);
|
led_state(PYB_LED_R2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,7 +292,6 @@ int main() {
|
||||||
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
|
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
|
||||||
//sys_tick_delay_ms(1000);
|
//sys_tick_delay_ms(1000);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Python!
|
// Python!
|
||||||
if (0) {
|
if (0) {
|
||||||
//const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
|
//const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
|
||||||
|
@ -570,7 +442,6 @@ int main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// benchmark C version of impl02.py
|
// benchmark C version of impl02.py
|
||||||
if (0) {
|
if (0) {
|
||||||
|
@ -663,7 +534,7 @@ int main() {
|
||||||
led_state(PYB_LED_G1, 0);
|
led_state(PYB_LED_G1, 0);
|
||||||
}
|
}
|
||||||
if (sys_tick_has_passed(stc, 500)) {
|
if (sys_tick_has_passed(stc, 500)) {
|
||||||
stc = sys_tick_counter;
|
stc += 500;
|
||||||
led_toggle(PYB_LED_G2);
|
led_toggle(PYB_LED_G2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <stm32f4xx.h>
|
||||||
|
#include <stm32f4xx_rcc.h>
|
||||||
|
#include <stm32f4xx_gpio.h>
|
||||||
|
|
||||||
|
#include "mma.h"
|
||||||
|
|
||||||
|
void mma_init() {
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1
|
||||||
|
//gpio_pin_init(GPIOB, 6 /* B6 is SCL */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
|
||||||
|
//gpio_pin_init(GPIOB, 7 /* B7 is SDA */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
|
||||||
|
//gpio_pin_af(GPIOB, 6, 4 /* AF 4 for I2C1 */);
|
||||||
|
//gpio_pin_af(GPIOB, 7, 4 /* AF 4 for I2C1 */);
|
||||||
|
// XXX untested GPIO init! (was above code)
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
|
||||||
|
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||||
|
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
|
||||||
|
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
|
||||||
|
|
||||||
|
// get clock speeds
|
||||||
|
RCC_ClocksTypeDef rcc_clocks;
|
||||||
|
RCC_GetClocksFreq(&rcc_clocks);
|
||||||
|
|
||||||
|
// disable the I2C peripheral before we configure it
|
||||||
|
I2C1->CR1 &= ~I2C_CR1_PE;
|
||||||
|
|
||||||
|
// program peripheral input clock
|
||||||
|
I2C1->CR2 = 4; // no interrupts; 4 MHz (hopefully!) (could go up to 42MHz)
|
||||||
|
|
||||||
|
// configure clock control reg
|
||||||
|
uint32_t freq = rcc_clocks.PCLK1_Frequency / (100000 << 1); // want 100kHz, this is the formula for freq
|
||||||
|
I2C1->CCR = freq; // standard mode (speed), freq calculated as above
|
||||||
|
|
||||||
|
// configure rise time reg
|
||||||
|
I2C1->TRISE = (rcc_clocks.PCLK1_Frequency / 1000000) + 1; // formula for trise, gives maximum rise time
|
||||||
|
|
||||||
|
// enable the I2C peripheral
|
||||||
|
I2C1->CR1 |= I2C_CR1_PE;
|
||||||
|
|
||||||
|
// set START bit in CR1 to generate a start cond!
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t i2c_get_sr() {
|
||||||
|
// must read SR1 first, then SR2, as the read can clear some flags
|
||||||
|
uint32_t sr1 = I2C1->SR1;
|
||||||
|
uint32_t sr2 = I2C1->SR2;
|
||||||
|
return (sr2 << 16) | sr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mma_restart(uint8_t addr, int write) {
|
||||||
|
// send start condition
|
||||||
|
I2C1->CR1 |= I2C_CR1_START;
|
||||||
|
|
||||||
|
// wait for BUSY, MSL and SB --> Slave has acknowledged start condition
|
||||||
|
while ((i2c_get_sr() & 0x00030001) != 0x00030001) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write) {
|
||||||
|
// send address and write bit
|
||||||
|
I2C1->DR = (addr << 1) | 0;
|
||||||
|
// wait for BUSY, MSL, ADDR, TXE and TRA
|
||||||
|
while ((i2c_get_sr() & 0x00070082) != 0x00070082) {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// send address and read bit
|
||||||
|
I2C1->DR = (addr << 1) | 1;
|
||||||
|
// wait for BUSY, MSL and ADDR flags
|
||||||
|
while ((i2c_get_sr() & 0x00030002) != 0x00030002) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mma_start(uint8_t addr, int write) {
|
||||||
|
// wait until I2C is not busy
|
||||||
|
while (I2C1->SR2 & I2C_SR2_BUSY) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// do rest of start
|
||||||
|
mma_restart(addr, write);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mma_send_byte(uint8_t data) {
|
||||||
|
// send byte
|
||||||
|
I2C1->DR = data;
|
||||||
|
// wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted)
|
||||||
|
int timeout = 1000000;
|
||||||
|
while ((i2c_get_sr() & 0x00070084) != 0x00070084) {
|
||||||
|
if (timeout-- <= 0) {
|
||||||
|
printf("mma_send_byte timed out!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t mma_read_ack() {
|
||||||
|
// enable ACK of received byte
|
||||||
|
I2C1->CR1 |= I2C_CR1_ACK;
|
||||||
|
// wait for BUSY, MSL and RXNE (byte received)
|
||||||
|
while ((i2c_get_sr() & 0x00030040) != 0x00030040) {
|
||||||
|
}
|
||||||
|
// read and return data
|
||||||
|
uint8_t data = I2C1->DR;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t mma_read_nack() {
|
||||||
|
// disable ACK of received byte (to indicate end of receiving)
|
||||||
|
I2C1->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
|
||||||
|
// last byte should apparently also generate a stop condition
|
||||||
|
I2C1->CR1 |= I2C_CR1_STOP;
|
||||||
|
// wait for BUSY, MSL and RXNE (byte received)
|
||||||
|
while ((i2c_get_sr() & 0x00030040) != 0x00030040) {
|
||||||
|
}
|
||||||
|
// read and return data
|
||||||
|
uint8_t data = I2C1->DR;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mma_stop() {
|
||||||
|
// send stop condition
|
||||||
|
I2C1->CR1 |= I2C_CR1_STOP;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
void mma_init();
|
||||||
|
void mma_restart(uint8_t addr, int write);
|
||||||
|
void mma_start(uint8_t addr, int write);
|
||||||
|
void mma_send_byte(uint8_t data);
|
||||||
|
uint8_t mma_read_ack();
|
||||||
|
uint8_t mma_read_nack();
|
||||||
|
void mma_stop();
|
|
@ -53,6 +53,14 @@ void storage_init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t storage_get_block_size() {
|
||||||
|
return BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t storage_get_block_count() {
|
||||||
|
return FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
void storage_flush() {
|
void storage_flush() {
|
||||||
cache_flush();
|
cache_flush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
void storage_init();
|
void storage_init();
|
||||||
|
uint32_t storage_get_block_size();
|
||||||
|
uint32_t storage_get_block_count();
|
||||||
void storage_flush();
|
void storage_flush();
|
||||||
bool storage_read_block(uint8_t *dest, uint32_t block);
|
bool storage_read_block(uint8_t *dest, uint32_t block);
|
||||||
bool storage_write_block(const uint8_t *src, uint32_t block);
|
bool storage_write_block(const uint8_t *src, uint32_t block);
|
||||||
|
|
|
@ -8,6 +8,7 @@ void sys_tick_init() {
|
||||||
// sys-tick interrupt called at 1ms intervals
|
// sys-tick interrupt called at 1ms intervals
|
||||||
sys_tick_counter = 0;
|
sys_tick_counter = 0;
|
||||||
SysTick_Config(SystemCoreClock / 1000);
|
SysTick_Config(SystemCoreClock / 1000);
|
||||||
|
NVIC_SetPriority(SysTick_IRQn, 0); // make it highest priority
|
||||||
}
|
}
|
||||||
|
|
||||||
// called on SysTick interrupt
|
// called on SysTick interrupt
|
||||||
|
|
Loading…
Reference in New Issue