Skip to content

Commit 5d3b4e8

Browse files
committed
Fix lost serial bytes during flash operations
-Keep interrupts enabled during flash operations -Shortened I2C ISR
1 parent 831fed9 commit 5d3b4e8

File tree

4 files changed

+76
-49
lines changed

4 files changed

+76
-49
lines changed

source/board/microbitv2/microbitv2.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#include "virtual_fs.h"
4141
#include "vfs_manager.h"
4242
#include "cortex_m.h"
43-
#include "FlashPrg.h"
43+
#include "fsl_flash.h"
4444

4545
#ifdef DRAG_N_DROP_SUPPORT
4646
#include "flash_intf.h"
@@ -90,6 +90,7 @@ extern target_cfg_t target_device_nrf52_64;
9090
extern main_usb_connect_t usb_state;
9191
extern bool go_to_sleep;
9292
extern i2c_slave_handle_t g_s_handle;
93+
extern flash_config_t g_flash;
9394

9495
typedef enum main_shutdown_state {
9596
MAIN_SHUTDOWN_WAITING = 0,
@@ -762,11 +763,33 @@ static bool file_extension_allowed(const vfs_filename_t filename)
762763
return false;
763764
}
764765

766+
static uint32_t erase_storage_sector(uint32_t adr)
767+
{
768+
int status = FLASH_Erase(&g_flash, adr, g_flash.PFlashSectorSize, kFLASH_apiEraseKey);
769+
if (status == kStatus_Success)
770+
{
771+
status = FLASH_VerifyErase(&g_flash, adr, g_flash.PFlashSectorSize, kFLASH_marginValueNormal);
772+
}
773+
return status;
774+
}
775+
776+
static uint32_t program_storage_page(uint32_t adr, uint32_t sz, uint32_t *buf)
777+
{
778+
int status = FLASH_Program(&g_flash, adr, buf, sz);
779+
if (status == kStatus_Success)
780+
{
781+
// Must use kFlashMargin_User, or kFlashMargin_Factory for verify program
782+
status = FLASH_VerifyProgram(&g_flash, adr, sz,
783+
buf, kFLASH_marginValueUser,
784+
NULL, NULL);
785+
}
786+
return status;
787+
}
788+
765789
static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
766790
i2cFlashCmd_t* pI2cCommand = (i2cFlashCmd_t*) pData;
767791

768792
uint32_t status = 0;
769-
cortex_int_state_t state;
770793

771794
uint32_t storage_address = pI2cCommand->cmdData.write.addr2 << 16 |
772795
pI2cCommand->cmdData.write.addr1 << 8 |
@@ -781,10 +804,8 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
781804
case gFlashDataWrite_c:
782805
/* Validate length field matches with I2C Write data */
783806
if (size == length + 8) {
784-
/* Address range and alignment validation done inside ProgramPage() */
785-
state = cortex_int_get_and_disable();
786-
status = ProgramPage(address, length, (uint32_t *) data);
787-
cortex_int_restore(state);
807+
/* Address range and alignment validation done inside program_storage_page() */
808+
status = program_storage_page(address, length, (uint32_t *) data);
788809

789810
if (0 != status) {
790811
pI2cCommand->cmdId = gFlashError_c;
@@ -832,9 +853,7 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
832853
start_addr < (FLASH_CONFIG_ADDRESS + FLASH_INTERFACE_SIZE) &&
833854
end_addr < (FLASH_CONFIG_ADDRESS + FLASH_INTERFACE_SIZE)) {
834855
for (uint32_t addr = start_addr; addr <= end_addr && status == 0; addr += DAPLINK_SECTOR_SIZE) {
835-
state = cortex_int_get_and_disable();
836-
status = EraseSector(addr);
837-
cortex_int_restore(state);
856+
status = erase_storage_sector(addr);
838857
}
839858

840859
if (status != 0) {
@@ -925,26 +944,20 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
925944
// Check first is config is already present in flash
926945
// If differences are found, erase and write new config
927946
if (0 != memcmp(&gflashConfig, (void *)FLASH_CONFIG_ADDRESS, sizeof(flashConfig_t))) {
928-
state = cortex_int_get_and_disable();
929-
status = EraseSector(FLASH_CONFIG_ADDRESS);
930-
cortex_int_restore(state);
947+
status = erase_storage_sector(FLASH_CONFIG_ADDRESS);
931948

932949
if (status != 0) {
933950
pI2cCommand->cmdId = gFlashError_c;
934951
}
935952
else {
936-
state = cortex_int_get_and_disable();
937-
status = ProgramPage(FLASH_CONFIG_ADDRESS, sizeof(flashConfig_t), (uint32_t *) &gflashConfig);
938-
cortex_int_restore(state);
953+
status = program_storage_page(FLASH_CONFIG_ADDRESS, sizeof(flashConfig_t), (uint32_t *) &gflashConfig);
939954
}
940955
}
941956
i2c_fillBuffer((uint8_t*) pI2cCommand, 0, 1);
942957
break;
943958
case gFlashCfgErase_c:
944959
// Erase flash sector containing flash config
945-
state = cortex_int_get_and_disable();
946-
status = EraseSector(FLASH_CONFIG_ADDRESS);
947-
cortex_int_restore(state);
960+
status = erase_storage_sector(FLASH_CONFIG_ADDRESS);
948961

949962
if (status != 0) {
950963
pI2cCommand->cmdId = gFlashError_c;

source/daplink/interface/main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
// Reset events
5454
#define FLAGS_MAIN_RESET (1 << 2)
5555
// Other Events
56+
#define FLAGS_BOARD_EVENT (1 << 3)
5657
#define FLAGS_MAIN_POWERDOWN (1 << 4)
5758
#define FLAGS_MAIN_DISABLEDEBUG (1 << 5)
5859
#define FLAGS_MAIN_PROC_USB (1 << 9)
@@ -133,6 +134,11 @@ __WEAK void board_handle_powerdown()
133134
// TODO: put the interface chip in sleep mode
134135
}
135136

137+
__WEAK void board_custom_event()
138+
{
139+
140+
}
141+
136142
// Timer task, set flags every 30mS and 90mS
137143
void timer_task_30mS(void * arg)
138144
{
@@ -182,6 +188,13 @@ void main_powerdown_event(void)
182188
return;
183189
}
184190

191+
// Set custom board event
192+
void main_board_event(void)
193+
{
194+
osThreadFlagsSet(main_task_id, FLAGS_BOARD_EVENT);
195+
return;
196+
}
197+
185198
// Disable debug on target
186199
void main_disable_debug_event(void)
187200
{
@@ -285,6 +298,7 @@ void main_task(void * arg)
285298
| FLAGS_MAIN_DISABLEDEBUG // Disable target debug
286299
| FLAGS_MAIN_PROC_USB // process usb events
287300
| FLAGS_MAIN_CDC_EVENT // cdc event
301+
| FLAGS_BOARD_EVENT // custom board event
288302
, osFlagsWaitAny
289303
, osWaitForever);
290304

@@ -324,6 +338,10 @@ void main_task(void * arg)
324338
if (flags & FLAGS_MAIN_CDC_EVENT) {
325339
cdc_process_event();
326340
}
341+
342+
if (flags & FLAGS_BOARD_EVENT) {
343+
board_custom_event();
344+
}
327345

328346
if (flags & FLAGS_MAIN_90MS) {
329347
// Update USB busy status

source/daplink/interface/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern "C" {
4848
void main_reset_target(uint8_t send_unique_id);
4949
void main_usb_set_test_mode(bool enabled);
5050
void main_powerdown_event(void);
51+
void main_board_event(void);
5152
void main_disable_debug_event(void);
5253
void main_cdc_send_event(void);
5354
void main_msc_disconnect_event(void);

source/hic_hal/freescale/kl27z/i2c.c

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "fsl_clock.h"
44
#include "fsl_port.h"
55
#include "settings.h" // for config_get_overflow_detect
6+
#include "main.h"
67

78
/* I2C source clock */
89
#define I2C_SLAVE_BASEADDR I2C1
@@ -13,21 +14,17 @@
1314
#define I2C_SLAVE_UPPER_ADDR_7BIT (0x72U)
1415
#define I2C_DATA_LENGTH (1024U + 8U)
1516

16-
// We'll start with 5 RX commands
17-
#define RX_CMDS_LENGTH 5
18-
#define I2C_CMD_SLEEP 0xABU
1917

2018
static uint8_t g_slave_TX_buff[I2C_DATA_LENGTH];
2119
static uint8_t g_slave_RX_buff[I2C_DATA_LENGTH];
2220
i2c_slave_handle_t g_s_handle;
2321
static volatile bool g_SlaveCompletionFlag = false;
2422
static volatile bool g_SlaveRxFlag = false;
25-
uint8_t address_match = 0;
23+
static uint8_t address_match = 0;
24+
static uint32_t transferredCount = 0;
2625

2726
static i2cWriteCallback_t pfWriteCommsCallback = NULL;
2827
static i2cReadCallback_t pfReadCommsCallback = NULL;
29-
static i2cWriteCallback_t pfWriteHIDCallback = NULL;
30-
static i2cReadCallback_t pfReadHIDCallback = NULL;
3128
static i2cWriteCallback_t pfWriteFlashCallback = NULL;
3229
static i2cReadCallback_t pfReadFlashCallback = NULL;
3330

@@ -46,6 +43,7 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
4643
/* Update information for transmit process */
4744
xfer->data = g_slave_TX_buff;
4845
xfer->dataSize = I2C_DATA_LENGTH;
46+
g_SlaveRxFlag = false;
4947
break;
5048

5149
/* Receive request */
@@ -65,32 +63,12 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
6563
g_SlaveCompletionFlag = true;
6664
xfer->data = NULL;
6765
xfer->dataSize = 0;
66+
transferredCount = xfer->transferredCount;
6867

6968
// Default driver couldn't differentiate between RX or TX completion
7069
// Check flag set in kI2C_SlaveReceiveEvent
71-
if (g_SlaveRxFlag) {
72-
g_SlaveRxFlag = false;
73-
74-
if (pfWriteCommsCallback && address_match == I2C_SLAVE_NRF_KL_COMMS) {
75-
pfWriteCommsCallback(&g_slave_RX_buff[0], xfer->transferredCount);
76-
}
77-
if (pfWriteHIDCallback && address_match == I2C_SLAVE_HID) {
78-
pfWriteHIDCallback(&g_slave_RX_buff[0], xfer->transferredCount);
79-
}
80-
if (pfWriteFlashCallback && address_match == I2C_SLAVE_FLASH) {
81-
pfWriteFlashCallback(&g_slave_RX_buff[0], xfer->transferredCount);
82-
}
83-
} else {
84-
if (pfReadCommsCallback && address_match == I2C_SLAVE_NRF_KL_COMMS) {
85-
pfReadCommsCallback(&g_slave_TX_buff[0], xfer->transferredCount);
86-
}
87-
if (pfReadHIDCallback && address_match == I2C_SLAVE_HID) {
88-
pfReadHIDCallback(&g_slave_TX_buff[0], xfer->transferredCount);
89-
}
90-
if (pfReadFlashCallback && address_match == I2C_SLAVE_FLASH) {
91-
pfReadFlashCallback(&g_slave_TX_buff[0], xfer->transferredCount);
92-
}
93-
}
70+
71+
main_board_event();
9472
break;
9573

9674
default:
@@ -99,6 +77,25 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
9977
}
10078
}
10179

80+
void board_custom_event() {
81+
82+
if (g_SlaveRxFlag) {
83+
if (pfWriteCommsCallback && address_match == I2C_SLAVE_NRF_KL_COMMS) {
84+
pfWriteCommsCallback(&g_slave_RX_buff[0], transferredCount);
85+
}
86+
if (pfWriteFlashCallback && address_match == I2C_SLAVE_FLASH) {
87+
pfWriteFlashCallback(&g_slave_RX_buff[0], transferredCount);
88+
}
89+
} else {
90+
if (pfReadCommsCallback && address_match == I2C_SLAVE_NRF_KL_COMMS) {
91+
pfReadCommsCallback(&g_slave_TX_buff[0], transferredCount);
92+
}
93+
if (pfReadFlashCallback && address_match == I2C_SLAVE_FLASH) {
94+
pfReadFlashCallback(&g_slave_TX_buff[0], transferredCount);
95+
}
96+
}
97+
}
98+
10299
static void i2c_init_pins(void) {
103100
/* Port C Clock Gate Control: Clock enabled */
104101
CLOCK_EnableClock(kCLOCK_PortC);
@@ -173,7 +170,6 @@ status_t i2c_RegisterWriteCallback(i2cWriteCallback_t writeCallback, uint8_t sla
173170
pfWriteCommsCallback = writeCallback;
174171
break;
175172
case I2C_SLAVE_HID:
176-
pfWriteHIDCallback = writeCallback;
177173
break;
178174
case I2C_SLAVE_FLASH:
179175
pfWriteFlashCallback = writeCallback;
@@ -195,7 +191,6 @@ status_t i2c_RegisterReadCallback(i2cReadCallback_t readCallback, uint8_t slaveA
195191
pfReadCommsCallback = readCallback;
196192
break;
197193
case I2C_SLAVE_HID:
198-
pfReadHIDCallback = readCallback;
199194
break;
200195
case I2C_SLAVE_FLASH:
201196
pfReadFlashCallback = readCallback;

0 commit comments

Comments
 (0)